Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 0 additions & 110 deletions .github/workflows/linuxpackage.yml

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Make sure your have go1.11+ already installed
### Install
```bash
$ make install
```
```

### Run-delivery
```bash
Expand Down
86 changes: 86 additions & 0 deletions bridge/setu/processor/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package processor
import (
"context"
"encoding/json"
"fmt"
"time"

checkpointTypes "github.com/maticnetwork/heimdall/checkpoint/types"
Expand All @@ -22,6 +23,10 @@ import (
hmTypes "github.com/maticnetwork/heimdall/types"
)

const (
defaultDelayDuration = 10 * time.Second
)

// StakingProcessor - process staking related events
type StakingProcessor struct {
BaseProcessor
Expand Down Expand Up @@ -200,6 +205,17 @@ func (sp *StakingProcessor) sendUnstakeInitToHeimdall(eventName string, logBytes
return nil
}

validNonce, nonceDelay, err := sp.checkValidNonce(event.ValidatorId.Uint64(), event.Nonce.Uint64())
if err != nil {
sp.Logger.Error("Error while validating nonce for the validator", "error", err)
return err
}

if !validNonce {
sp.Logger.Info("Ignoring task to send unstake-init to heimdall as nonce is out of order")
return tasks.NewErrRetryTaskLater("Nonce out of order", defaultDelayDuration*time.Duration(nonceDelay))
}

sp.Logger.Info(
"✅ Received task to send unstake-init to heimdall",
"event", eventName,
Expand Down Expand Up @@ -327,6 +343,18 @@ func (sp *StakingProcessor) sendSignerChangeToHeimdall(eventName string, logByte
)
return nil
}

validNonce, nonceDelay, err := sp.checkValidNonce(event.ValidatorId.Uint64(), event.Nonce.Uint64())
if err != nil {
sp.Logger.Error("Error while validating nonce for the validator", "error", err)
return err
}

if !validNonce {
sp.Logger.Info("Ignoring task to send signer-change to heimdall as nonce is out of order")
return tasks.NewErrRetryTaskLater("Nonce out of order", defaultDelayDuration*time.Duration(nonceDelay))
}

sp.Logger.Info(
"✅ Received task to send signer-change to heimdall",
"event", eventName,
Expand Down Expand Up @@ -681,3 +709,61 @@ func (sp *StakingProcessor) getStakingContext(rootChain string) (*StakingContext
ChainmanagerParams: chainmanagerParams,
}, nil
}

func (sp *StakingProcessor) checkValidNonce(validatorId uint64, txnNonce uint64) (bool, uint64, error) {
currentNonce, currentHeight, err := util.GetValidatorNonce(sp.cliCtx, validatorId)
if err != nil {
sp.Logger.Error("Failed to fetch validator nonce and height data from API", "validatorId", validatorId)
return false, 0, err
}

if currentNonce+1 != txnNonce {
sp.Logger.Error("Nonce for the given event not in order", "validatorId", validatorId, "currentNonce", currentNonce, "txnNonce", txnNonce)
return false, txnNonce - currentNonce, nil
}

stakingTxnCount, err := queryTxCount(sp.cliCtx, validatorId, currentHeight)
if err != nil {
sp.Logger.Error("Failed to query stake txns by txquery for the given validator", "validatorId", validatorId)
return false, 0, err
}

if stakingTxnCount != 0 {
sp.Logger.Info("Recent staking txn count for the given validator is not zero", "validatorId", validatorId, "currentNonce", currentNonce, "txnNonce", txnNonce, "currentHeight", currentHeight)
return false, 1, nil
}

return true, 0, nil
}

func queryTxCount(cliCtx cliContext.CLIContext, validatorId uint64, currentHeight int64) (int, error) {
const (
defaultPage = 1
defaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19
)

stakingTxnMsgMap := map[string]string{
"validator-stake-update": "stake-update",
"validator-join": "validator-join",
"signer-update": "signer-update",
"validator-exit": "validator-exit",
}

for msg, action := range stakingTxnMsgMap {
events := []string{
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, msg),
fmt.Sprintf("%s.%s=%d", action, "validator-id", validatorId),
fmt.Sprintf("%s.%s>%d", "tx", "height", currentHeight-3),
}

searchResult, err := helper.QueryTxsByEvents(cliCtx, events, defaultPage, defaultLimit)
if err != nil {
return 0, err
}

if searchResult.TotalCount != 0 {
return searchResult.TotalCount, nil
}
}
return 0, nil
}
28 changes: 26 additions & 2 deletions bridge/setu/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ func IsInProposerList(cliCtx cliContext.CLIContext, count uint64) (bool, error)
}

//default offset 0
func CalculateTaskDelay(cliCtx cliContext.CLIContext) (bool, time.Duration){
return CalculateTaskDelayWithOffset(cliCtx,0)
func CalculateTaskDelay(cliCtx cliContext.CLIContext) (bool, time.Duration) {
return CalculateTaskDelayWithOffset(cliCtx, 0)
}

// CalculateTaskDelay calculates delay required for current validator to propose the tx
Expand Down Expand Up @@ -462,3 +462,27 @@ func GetNextStakingRecord(cliCtx cliContext.CLIContext, rootChain string) (*stak

return &stakingRecord, nil
}

// GetValidatorNonce fethes validator nonce and height
func GetValidatorNonce(cliCtx cliContext.CLIContext, validatorID uint64) (uint64, int64, error) {
var validator hmtypes.Validator

result, err := helper.FetchFromAPI(cliCtx,
helper.GetHeimdallServerEndpoint(fmt.Sprintf(ValidatorURL, strconv.FormatUint(validatorID, 10))),
)

if err != nil {
logger.Error("Error fetching validator data", "error", err)
return 0, 0, err
}

err = json.Unmarshal(result.Result, &validator)
if err != nil {
logger.Error("error unmarshalling validator data", "error", err)
return 0, 0, err
}

logger.Debug("Validator data recieved ", "validator", validator.String())

return validator.Nonce, result.Height, nil
}
5 changes: 0 additions & 5 deletions checkpoint/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,31 +105,26 @@ func SendCheckpointTx(cdc *codec.Codec) *cobra.Command {
}

// start block

startBlockStr := viper.GetString(FlagStartBlock)
if startBlockStr == "" {
return fmt.Errorf("start block cannot be empty")
}

startBlock, err := strconv.ParseUint(startBlockStr, 10, 64)
if err != nil {
return err
}

// end block

endBlockStr := viper.GetString(FlagEndBlock)
if endBlockStr == "" {
return fmt.Errorf("end block cannot be empty")
}

endBlock, err := strconv.ParseUint(endBlockStr, 10, 64)
if err != nil {
return err
}

// root hash

rootHashStr := viper.GetString(FlagRootHash)
if rootHashStr == "" {
return fmt.Errorf("root hash cannot be empty")
Expand Down
3 changes: 2 additions & 1 deletion checkpoint/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/maticnetwork/heimdall/app"
cmTypes "github.com/maticnetwork/heimdall/chainmanager/types"
"github.com/maticnetwork/heimdall/checkpoint/types"
errs "github.com/maticnetwork/heimdall/common"

Expand Down Expand Up @@ -425,7 +426,7 @@ func (suite *HandlerTestSuite) SendCheckpoint(header hmTypes.Checkpoint) (res sd
hmTypes.RootChainTypeStake,
)

suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock).Return(true)
suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock+cmTypes.DefaultMaticchainTxConfirmations).Return(true)
suite.contractCaller.On("GetRootHash", header.StartBlock, header.EndBlock, uint64(1024)).Return(header.RootHash.Bytes(), nil)

// send checkpoint to handler
Expand Down
3 changes: 2 additions & 1 deletion checkpoint/side_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ func NewSideTxHandler(k Keeper, contractCaller helper.IContractCaller) hmTypes.S
func SideHandleMsgCheckpoint(ctx sdk.Context, k Keeper, msg types.MsgCheckpoint, contractCaller helper.IContractCaller) (result abci.ResponseDeliverSideTx) {
// get params
params := k.GetParams(ctx)
maticTxConfirmations := k.ck.GetParams(ctx).MaticchainTxConfirmations

// logger
logger := k.Logger(ctx)

// validate checkpoint
validCheckpoint, err := types.ValidateCheckpoint(msg.StartBlock, msg.EndBlock, msg.RootHash, params.MaxCheckpointLength, contractCaller)
validCheckpoint, err := types.ValidateCheckpoint(msg.StartBlock, msg.EndBlock, msg.RootHash, params.MaxCheckpointLength, contractCaller, maticTxConfirmations)
if err != nil {
logger.Error("Error validating checkpoint",
"error", err,
Expand Down
7 changes: 4 additions & 3 deletions checkpoint/side_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/maticnetwork/heimdall/app"
cmTypes "github.com/maticnetwork/heimdall/chainmanager/types"
"github.com/maticnetwork/heimdall/checkpoint"
chSim "github.com/maticnetwork/heimdall/checkpoint/simulation"
"github.com/maticnetwork/heimdall/checkpoint/types"
Expand Down Expand Up @@ -90,7 +91,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgCheckpoint() {
hmTypes.RootChainTypeEth,
)

suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock).Return(true)
suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock+cmTypes.DefaultMaticchainTxConfirmations).Return(true)
suite.contractCaller.On("GetRootHash", header.StartBlock, header.EndBlock, uint64(1024)).Return(header.RootHash.Bytes(), nil)

result := suite.sideHandler(ctx, msgCheckpoint)
Expand All @@ -115,7 +116,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgCheckpoint() {
hmTypes.RootChainTypeEth,
)

suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock).Return(true)
suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock+cmTypes.DefaultMaticchainTxConfirmations).Return(true)
suite.contractCaller.On("GetRootHash", header.StartBlock, header.EndBlock, uint64(1024)).Return(nil, nil)

result := suite.sideHandler(ctx, msgCheckpoint)
Expand Down Expand Up @@ -143,7 +144,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgCheckpoint() {
hmTypes.RootChainTypeEth,
)

suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock).Return(true)
suite.contractCaller.On("CheckIfBlocksExist", header.EndBlock+cmTypes.DefaultMaticchainTxConfirmations).Return(true)
suite.contractCaller.On("GetRootHash", header.StartBlock, header.EndBlock, uint64(1024)).Return([]byte{1}, nil)

result := suite.sideHandler(ctx, msgCheckpoint)
Expand Down
4 changes: 2 additions & 2 deletions checkpoint/types/merkel.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import (
)

// ValidateCheckpoint - Validates if checkpoint rootHash matches or not
func ValidateCheckpoint(start uint64, end uint64, rootHash hmTypes.HeimdallHash, checkpointLength uint64, contractCaller helper.IContractCaller) (bool, error) {
func ValidateCheckpoint(start uint64, end uint64, rootHash hmTypes.HeimdallHash, checkpointLength uint64, contractCaller helper.IContractCaller, confirmations uint64) (bool, error) {
// Check if blocks exist locally
if !contractCaller.CheckIfBlocksExist(end) {
if !contractCaller.CheckIfBlocksExist(end + confirmations) {
return false, errors.New("blocks not found locally")
}

Expand Down
Loading