diff --git a/bridge/setu/listener/heimdall.go b/bridge/setu/listener/heimdall.go index 64a19e43..e1d0aaac 100644 --- a/bridge/setu/listener/heimdall.go +++ b/bridge/setu/listener/heimdall.go @@ -3,6 +3,7 @@ package listener import ( "context" "encoding/json" + "fmt" "math/big" "strconv" "sync" @@ -112,6 +113,9 @@ func (hl *HeimdallListener) StartPolling(ctx context.Context, pollInterval time. hl.Logger.Info("Fetching new events between", "fromBlock", fromBlock, "toBlock", toBlock) + // set to avoid deduplicate checkpoint-sync events by (rootChain, number, startBlock, endBlock) + checkpointSyncSet := make(map[string]struct{}) + // Querying and processing Begin events for i := fromBlock; i <= toBlock; i++ { events, err := helper.GetBeginBlockEvents(hl.httpClient, int64(i)) @@ -119,7 +123,7 @@ func (hl *HeimdallListener) StartPolling(ctx context.Context, pollInterval time. hl.Logger.Error("Error fetching begin block events", "error", err) } for _, event := range events { - hl.ProcessBlockEvent(sdk.StringifyEvent(event), int64(i)) + hl.ProcessBlockEvent(sdk.StringifyEvent(event), int64(i), checkpointSyncSet) } } @@ -202,11 +206,18 @@ func (hl *HeimdallListener) fetchFromAndToBlock() (uint64, uint64, error) { return fromBlock, toBlock, err } } + maxQueryBlocks := helper.GetConfig().HeimdallMaxQueryBlocks + if maxQueryBlocks == 0 { + maxQueryBlocks = helper.DefaultHeimdallMaxQueryBlocks + } + if maxQueryBlocks != 0 && toBlock-fromBlock > uint64(maxQueryBlocks) { + toBlock = fromBlock + uint64(maxQueryBlocks) + } return fromBlock, toBlock, err } // ProcessBlockEvent - process Blockevents (BeginBlock, EndBlock events) from heimdall. -func (hl *HeimdallListener) ProcessBlockEvent(event sdk.StringEvent, blockHeight int64) { +func (hl *HeimdallListener) ProcessBlockEvent(event sdk.StringEvent, blockHeight int64, checkpointSyncSet map[string]struct{}) { hl.Logger.Info("Received block event from Heimdall", "eventType", event.Type, "height", blockHeight) eventBytes, err := json.Marshal(event) if err != nil { @@ -218,6 +229,13 @@ func (hl *HeimdallListener) ProcessBlockEvent(event sdk.StringEvent, blockHeight case checkpointTypes.EventTypeCheckpoint: hl.sendBlockTask("sendCheckpointToRootchain", eventBytes, blockHeight) case checkpointTypes.EventTypeCheckpointSync: + key := hl.getCheckpointSyncKey(event) + if _, exists := checkpointSyncSet[key]; exists { + hl.Logger.Info("CheckpointSync duplicate, skip sending task", "key", key) + return + } + + checkpointSyncSet[key] = struct{}{} hl.sendBlockTask("sendCheckpointSyncToStakeChain", eventBytes, blockHeight) case slashingTypes.EventTypeSlashLimit: hl.sendBlockTask("sendTickToHeimdall", eventBytes, blockHeight) @@ -236,6 +254,24 @@ func (hl *HeimdallListener) ProcessBlockEvent(event sdk.StringEvent, blockHeight } } +func (hl *HeimdallListener) getCheckpointSyncKey(event sdk.StringEvent) string { + var rootChain string + var number, startBlock, endBlock uint64 + for _, attr := range event.Attributes { + switch attr.Key { + case checkpointTypes.AttributeKeyRootChain: + rootChain = attr.Value + case checkpointTypes.AttributeKeyHeaderIndex: + number, _ = strconv.ParseUint(attr.Value, 10, 64) + case checkpointTypes.AttributeKeyStartBlock: + startBlock, _ = strconv.ParseUint(attr.Value, 10, 64) + case checkpointTypes.AttributeKeyEndBlock: + endBlock, _ = strconv.ParseUint(attr.Value, 10, 64) + } + } + return fmt.Sprintf("%s_%d_%d_%d", rootChain, number, startBlock, endBlock) +} + func (hl *HeimdallListener) sendBlockTask(taskName string, eventBytes []byte, blockHeight int64) { // create machinery task signature := &tasks.Signature{ diff --git a/helper/config.go b/helper/config.go index 94f9f902..6d32c8a9 100644 --- a/helper/config.go +++ b/helper/config.go @@ -96,9 +96,10 @@ const ( DefaultBscBusyLimitTxs = 1000 DefaultTronBusyLimitTxs = 20000 - DefaultEthMaxQueryBlocks = 100 - DefaultBscMaxQueryBlocks = 5 - DefaultTronMaxQueryBlocks = 5 + DefaultEthMaxQueryBlocks = 100 + DefaultBscMaxQueryBlocks = 5 + DefaultTronMaxQueryBlocks = 5 + DefaultHeimdallMaxQueryBlocks = 1000 DefaultBttcChainID string = "15001" DefaultEnableIncreaseGasPrice = false @@ -166,9 +167,10 @@ type Configuration struct { BscUnconfirmedTxsBusyLimit int `mapstructure:"bsc_unconfirmed_txs_busy_limit"` // the busy limit of unconfirmed txs on heimdall for bsc TronUnconfirmedTxsBusyLimit int `mapstructure:"tron_unconfirmed_txs_busy_limit"` // the busy limit of unconfirmed txs on heimdall for tron - EthMaxQueryBlocks int64 `mapstructure:"eth_max_query_blocks"` // eth max number of blocks in one query logs - BscMaxQueryBlocks int64 `mapstructure:"bsc_max_query_blocks"` // bsc max number of blocks in one query logs - TronMaxQueryBlocks int64 `mapstructure:"tron_max_query_blocks"` // tron max number of blocks in one query logs + EthMaxQueryBlocks int64 `mapstructure:"eth_max_query_blocks"` // eth max number of blocks in one query logs + BscMaxQueryBlocks int64 `mapstructure:"bsc_max_query_blocks"` // bsc max number of blocks in one query logs + TronMaxQueryBlocks int64 `mapstructure:"tron_max_query_blocks"` // tron max number of blocks in one query logs + HeimdallMaxQueryBlocks int64 `mapstructure:"heimdall_max_query_blocks"` // heimdall max number of blocks in one query logs EnableIncreaseGasPrice bool `mapstructure:"enable_increase_gas_price"` // whether enable increase gas price when submit checkpoint to eth GasPriceIncreasePercent int64 `mapstructure:"gas_price_increase_percent"` // the increase percent of gas price when submit tx. newGasPrice = oldGasPrice * (100 + GasPriceIncreasePercent) / 100 @@ -330,9 +332,10 @@ func GetDefaultHeimdallConfig() Configuration { BscUnconfirmedTxsBusyLimit: DefaultBscBusyLimitTxs, TronUnconfirmedTxsBusyLimit: DefaultTronBusyLimitTxs, - EthMaxQueryBlocks: DefaultEthMaxQueryBlocks, - BscMaxQueryBlocks: DefaultBscMaxQueryBlocks, - TronMaxQueryBlocks: DefaultTronMaxQueryBlocks, + EthMaxQueryBlocks: DefaultEthMaxQueryBlocks, + BscMaxQueryBlocks: DefaultBscMaxQueryBlocks, + TronMaxQueryBlocks: DefaultTronMaxQueryBlocks, + HeimdallMaxQueryBlocks: DefaultHeimdallMaxQueryBlocks, EnableIncreaseGasPrice: DefaultEnableIncreaseGasPrice, GasPriceIncreasePercent: DefaultGasPriceIncreasePercent,