Skip to content

Commit

Permalink
MAT-1397 - Added nonce to Tick-ack flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mankenavenkatesh committed May 15, 2020
1 parent 99bc0f4 commit 20895a5
Show file tree
Hide file tree
Showing 19 changed files with 286 additions and 48 deletions.
26 changes: 25 additions & 1 deletion bridge/setu/processor/slashing.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,20 @@ func (sp *SlashingProcessor) sendTickToHeimdall(eventBytes string, blockHeight i
return err
}

//Get tickCount from HeimdallServer
tickCount := sp.fetchTickCount()

sp.Logger.Info("processing slash-limit event", "eventtype", event.Type)

sp.Logger.Info("✅ Creating and broadcasting Tick tx",
"id", tickCount+1,
"From", hmTypes.BytesToHeimdallAddress(helper.GetAddress()),
"latestSlashInoBytes", latestSlashInoBytes.String(),
)

// create msg Tick message
msg := slashingTypes.NewMsgTick(
tickCount+1,
hmTypes.BytesToHeimdallAddress(helper.GetAddress()),
latestSlashInoBytes,
)
Expand Down Expand Up @@ -178,6 +183,7 @@ func (sp *SlashingProcessor) sendTickAckToHeimdall(eventName string, logBytes st
if isOld, _ := sp.isOldTx(sp.cliCtx, vLog.TxHash.String(), uint64(vLog.Index)); isOld {
sp.Logger.Info("Ignoring task to send tick ack to heimdall as already processed",
"event", eventName,
"tickID", event.Nonce,
"totalSlashedAmount", event.Amount.Uint64(),
"txHash", hmTypes.BytesToHeimdallHash(vLog.TxHash.Bytes()),
"logIndex", uint64(vLog.Index),
Expand All @@ -188,6 +194,7 @@ func (sp *SlashingProcessor) sendTickAckToHeimdall(eventName string, logBytes st
sp.Logger.Info(
"✅ Received task to send tick-ack to heimdall",
"event", eventName,
"tickID", event.Nonce,
"totalSlashedAmount", event.Amount.Uint64(),
"txHash", hmTypes.BytesToHeimdallHash(vLog.TxHash.Bytes()),
"logIndex", uint64(vLog.Index),
Expand All @@ -197,7 +204,7 @@ func (sp *SlashingProcessor) sendTickAckToHeimdall(eventName string, logBytes st
// TODO - check if i am the proposer of this tick ack or not.

// create msg checkpoint ack message
msg := slashingTypes.NewMsgTickAck(helper.GetFromAddress(sp.cliCtx), event.Amount.Uint64(), hmTypes.BytesToHeimdallHash(vLog.TxHash.Bytes()), uint64(vLog.Index), vLog.BlockNumber)
msg := slashingTypes.NewMsgTickAck(helper.GetFromAddress(sp.cliCtx), event.Nonce.Uint64(), event.Amount.Uint64(), hmTypes.BytesToHeimdallHash(vLog.TxHash.Bytes()), uint64(vLog.Index), vLog.BlockNumber)

// return broadcast to heimdall
if err := sp.txBroadcaster.BroadcastToHeimdall(msg); err != nil {
Expand Down Expand Up @@ -339,6 +346,23 @@ func (sp *SlashingProcessor) fetchLatestSlashInoBytes() (slashInfoBytes hmTypes.
return slashInfoBytes, nil
}

// fetchTickCount - fetches tick count
func (sp *SlashingProcessor) fetchTickCount() uint64 {
sp.Logger.Info("Sending Rest call to Get Tick count")
response, err := helper.FetchFromAPI(sp.cliCtx, helper.GetHeimdallServerEndpoint(util.SlashingTickCountURL))
if err != nil {
sp.Logger.Error("Error while sending request for tick count", "Error", err)
return 0
}

var tickCount uint64
if err := json.Unmarshal(response.Result, &tickCount); err != nil {
sp.Logger.Error("Error unmarshalling tick count data ", "error", err)
return 0
}
return tickCount
}

// fetchTickSlashInfoList - fetches tick slash Info list
func (sp *SlashingProcessor) fetchTickSlashInfoList() (slashInfoList []*hmTypes.ValidatorSlashingInfo, err error) {
sp.Logger.Info("Sending Rest call to Get Tick SlashInfo list")
Expand Down
1 change: 1 addition & 0 deletions bridge/setu/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
LatestSlashInfoBytesURL = "/slashing/latest_slash_info_bytes"
TickSlashInfoListURL = "/slashing/tick_slash_infos"
SlashingTxStatusURL = "/slashing/isoldtx"
SlashingTickCountURL = "/slashing/tick-count"

TransactionTimeout = 1 * time.Minute
CommitTimeout = 2 * time.Minute
Expand Down
16 changes: 13 additions & 3 deletions common/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ const (
CodeInvalidReceipt CodeType = 5501
CodeSideTxValidationFailed CodeType = 5502

CodeValSigningInfoSave CodeType = 6501
CodeErrValUnjail CodeType = 6502
CodeSlashInfoDetails CodeType = 6503
CodeValSigningInfoSave CodeType = 6501
CodeErrValUnjail CodeType = 6502
CodeSlashInfoDetails CodeType = 6503
CodeTickNotInContinuity CodeType = 6504
CodeTickAckNotInContinuity CodeType = 6505
)

// -------- Invalid msg
Expand Down Expand Up @@ -345,3 +347,11 @@ func ErrUnjailValidator(codespace sdk.CodespaceType) sdk.Error {
func ErrSlashInfoDetails(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeSlashInfoDetails, "Wrong slash info details")
}

func ErrTickNotInContinuity(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeTickNotInContinuity, "Tick not in countinuity")
}

func ErrTickAckNotInContinuity(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeTickAckNotInContinuity, "Tick-ack not in countinuity")
}
41 changes: 26 additions & 15 deletions contracts/stakinginfo/stakinginfo.abi
Original file line number Diff line number Diff line change
Expand Up @@ -361,21 +361,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "logSlashed",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
Expand Down Expand Up @@ -728,6 +713,26 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nonce",
"type": "uint256"
}
],
"name": "logSlashed",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -971,6 +976,12 @@
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "nonce",
"type": "uint256"
}
],
"name": "Slashed",
Expand Down
55 changes: 32 additions & 23 deletions contracts/stakinginfo/stakinginfo.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions slashing/client/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ const (
FlagLogIndex = "log-index"
FlagAmount = "slashed-amount"
FlagSlashInfoBytes = "slashinfo-bytes"
FlagTickID = "tick-id"
FlagBlockNumber = "block-number"
)
7 changes: 7 additions & 0 deletions slashing/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func GetCmdTick(cdc *codec.Codec) *cobra.Command {
}

msg := types.NewMsgTick(
viper.GetUint64(FlagTickID),
proposer,
hmTypes.HexToHexBytes(slashInfoBytes),
)
Expand All @@ -119,7 +120,10 @@ func GetCmdTick(cdc *codec.Codec) *cobra.Command {

cmd.Flags().StringP(FlagProposerAddress, "p", "", "--proposer=<proposer-address>")
cmd.Flags().String(FlagSlashInfoBytes, "", "--slashinfo-bytes=<slashinfo-bytes>")
cmd.Flags().Uint64(FlagTickID, 1, "--tick-id=<tick-id>")

cmd.MarkFlagRequired(FlagSlashInfoBytes)
cmd.MarkFlagRequired(FlagTickID)

return cmd
}
Expand All @@ -145,6 +149,7 @@ func GetCmdTickAck(cdc *codec.Codec) *cobra.Command {

msg := types.NewMsgTickAck(
proposer,
viper.GetUint64(FlagTickID),
viper.GetUint64(FlagAmount),
hmTypes.HexToHeimdallHash(txHash),
uint64(viper.GetInt64(FlagLogIndex)),
Expand All @@ -161,13 +166,15 @@ func GetCmdTickAck(cdc *codec.Codec) *cobra.Command {
cmd.Flags().Uint64(FlagBlockNumber, 0, "--block-number=<block-number>")
cmd.Flags().String(FlagLogIndex, "", "--log-index=<log-index>")
cmd.Flags().Uint64(FlagAmount, 0, "--amount=<amount>")
cmd.Flags().Uint64(FlagTickID, 1, "--tick-id=<tick-id>")

if err := cmd.MarkFlagRequired(FlagBlockNumber); err != nil {
logger.Error("SendTickAckTx | MarkFlagRequired | FlagBlockNumber", "Error", err)
}
cmd.MarkFlagRequired(FlagTxHash)
cmd.MarkFlagRequired(FlagLogIndex)
cmd.MarkFlagRequired(FlagAmount)
cmd.MarkFlagRequired(FlagTickID)

return cmd
}
42 changes: 42 additions & 0 deletions slashing/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
"/slashing/isoldtx",
SlashingTxStatusHandlerFn(cliCtx),
).Methods("GET")

r.HandleFunc(
"/slashing/tick-count",
tickCountHandlerFn(cliCtx),
).Methods("GET")
}

// http request handler to query signing info
Expand Down Expand Up @@ -336,3 +341,40 @@ func SlashingTxStatusHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
rest.PostProcessResponse(w, cliCtx, res)
}
}

func tickCountHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

RestLogger.Debug("Fetching number of ticks from state")
tickCountBytes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryTickCount), nil)
if err != nil {
hmRest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

// check content
if ok := hmRest.ReturnNotFoundIfNoContent(w, tickCountBytes, "No tick count found"); !ok {
return
}

var tickCount uint64
if err := json.Unmarshal(tickCountBytes, &tickCount); err != nil {
hmRest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

result, err := json.Marshal(map[string]interface{}{"result": tickCount})
if err != nil {
RestLogger.Error("Error while marshalling resposne to Json", "error", err)
hmRest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, result)
}
}
14 changes: 14 additions & 0 deletions slashing/client/rest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ type UnjailReq struct {

type TickReq struct {
BaseReq rest.BaseReq `json:"base_req"`
ID uint64 `json:"ID"`
Proposer string `json:"proposer"`
SlashingInfoBytes string `json:"slashing_info_bytes"`
}

type TickAckReq struct {
BaseReq rest.BaseReq `json:"base_req"`
ID uint64 `json:"ID"`
Amount uint64 `json:"amount"`
TxHash string `json:"tx_hash"`
LogIndex uint64 `json:"log_index"`
Expand Down Expand Up @@ -95,7 +97,13 @@ func newTickRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}

msg := types.NewMsgTick(
req.ID,
hmTypes.HexToHeimdallAddress(req.Proposer),
hmTypes.HexToHexBytes(req.SlashingInfoBytes),
)
Expand All @@ -113,8 +121,14 @@ func newTickAckHandler(cliCtx context.CLIContext) http.HandlerFunc {
return
}

req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}

msg := types.NewMsgTickAck(
hmTypes.HexToHeimdallAddress(req.BaseReq.From),
req.ID,
req.Amount,
hmTypes.HexToHeimdallHash(req.TxHash),
req.LogIndex,
Expand Down
11 changes: 10 additions & 1 deletion slashing/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {

keeper.SetParams(ctx, data.Params)

// Set initial tick count
keeper.UpdateTickCountWithValue(ctx, data.TickCount)

}

// ExportGenesis writes the current store values
Expand All @@ -62,5 +65,11 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) (data types.GenesisState) {

bufSlashInfos, _ := keeper.GetBufferValSlashingInfos(ctx)
tickSlashInfos, _ := keeper.GetTickValSlashingInfos(ctx)
return types.NewGenesisState(params, signingInfos, missedBlocks, bufSlashInfos, tickSlashInfos)
return types.NewGenesisState(
params,
signingInfos,
missedBlocks,
bufSlashInfos,
tickSlashInfos,
keeper.GetTickCount(ctx))
}
16 changes: 16 additions & 0 deletions slashing/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func NewHandler(k Keeper, contractCaller helper.IContractCaller) sdk.Handler {
func handlerMsgTick(ctx sdk.Context, msg types.MsgTick, k Keeper, contractCaller helper.IContractCaller) sdk.Result {

k.Logger(ctx).Debug("✅ Validating tick msg",
"msgID", msg.ID,
"SlashInfoBytes", msg.SlashingInfoBytes.String(),
)

Expand All @@ -54,6 +55,13 @@ func handlerMsgTick(ctx sdk.Context, msg types.MsgTick, k Keeper, contractCaller
return hmCommon.ErrInvalidMsg(k.Codespace(), fmt.Sprintf("TotalSlashedAmount %v is less than SlashLimit", k.GetTotalSlashedAmount(ctx))).Result()
}

// check if tick msgs are in continuity
tickCount := k.GetTickCount(ctx)
if msg.ID != tickCount+1 {
k.Logger(ctx).Error("Tick not in countinuity", "msgID", msg.ID, "expectedMsgID", tickCount+1)
return hmCommon.ErrTickNotInContinuity(k.Codespace()).Result()
}

valSlashingInfos, err := k.GetBufferValSlashingInfos(ctx)
if err != nil {
k.Logger(ctx).Error("Error fetching slash Info list from buffer", "error", err)
Expand Down Expand Up @@ -140,6 +148,7 @@ func handleMsgUnjail(ctx sdk.Context, msg types.MsgUnjail, k Keeper, contractCal
func handleMsgTickAck(ctx sdk.Context, msg types.MsgTickAck, k Keeper, contractCaller helper.IContractCaller) sdk.Result {

k.Logger(ctx).Debug("✅ Validating TickAck msg",
"ID", msg.ID,
"SlashedAmount", msg.SlashedAmount,
"txHash", hmTypes.BytesToHeimdallHash(msg.TxHash.Bytes()),
"logIndex", uint64(msg.LogIndex),
Expand All @@ -157,6 +166,13 @@ func handleMsgTickAck(ctx sdk.Context, msg types.MsgTickAck, k Keeper, contractC
return hmCommon.ErrOldTx(k.Codespace()).Result()
}

// check if tick ack msgs are in continuity
tickCount := k.GetTickCount(ctx)
if msg.ID != tickCount {
k.Logger(ctx).Error("Tick-ack not in countinuity", "msgID", msg.ID, "expectedMsgID", tickCount)
return hmCommon.ErrTickAckNotInContinuity(k.Codespace()).Result()
}

return sdk.Result{
Events: ctx.EventManager().Events(),
}
Expand Down
Loading

0 comments on commit 20895a5

Please sign in to comment.