From 358bb83313d1f5e3048b11695b3a8d189299b37e Mon Sep 17 00:00:00 2001 From: trestin Date: Thu, 5 Sep 2024 22:11:55 +0800 Subject: [PATCH] fix apphash mismatch caused by unordered grouping of maps --- x/avs/keeper/impl_epoch_hook.go | 12 ++++++------ x/avs/keeper/task.go | 24 ++++++++++++++++++------ x/avs/types/types.go | 10 ++++------ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/x/avs/keeper/impl_epoch_hook.go b/x/avs/keeper/impl_epoch_hook.go index 7bf7b7118..593299aba 100644 --- a/x/avs/keeper/impl_epoch_hook.go +++ b/x/avs/keeper/impl_epoch_hook.go @@ -32,7 +32,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( // get all the task info bypass the epoch end // threshold calculation, signature verification, nosig quantity statistics taskResList := wrapper.keeper.GetTaskStatisticalEpochEndAVSs(ctx, epochIdentifier, epochNumber) - + // TODO:There should be a retry mechanism or compensation mechanism to handle cases of failure if len(taskResList) != 0 { groupedTasks := wrapper.keeper.GroupTasksByIDAndAddress(taskResList) for _, value := range groupedTasks { @@ -58,7 +58,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( } power, err := wrapper.keeper.operatorKeeper.GetOperatorOptedUSDValue(ctx, avsAddr, res.OperatorAddress) if err != nil || power.ActiveUSDValue.IsNegative() { - ctx.Logger().Error("Failed to update task result statistics", "task result", taskAddr, "error", err) + ctx.Logger().Error("Failed to update task result statistics,GetOperatorOptedUSDValue call failed!", "task result", taskAddr, "error", err) // Handle the error gracefully, continue to the next continue } @@ -73,7 +73,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( } taskInfo, err := wrapper.keeper.GetTaskInfo(ctx, strconv.FormatUint(taskID, 10), taskAddr) if err != nil { - ctx.Logger().Error("Failed to update task result statistics", "task result", taskAddr, "error", err) + ctx.Logger().Error("Failed to update task result statistics,GetTaskInfo call failed!", "task result", taskAddr, "error", err) // Handle the error gracefully, continue to the next continue } @@ -85,14 +85,14 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( taskPowerTotal, err := wrapper.keeper.operatorKeeper.GetAVSUSDValue(ctx, avsAddr) if err != nil || taskPowerTotal.IsZero() || operatorPowerTotal.IsZero() { - ctx.Logger().Error("Failed to update task result statistics", "task result", taskAddr, "error", err) + ctx.Logger().Error("Failed to update task result statistics,GetAVSUSDValue call failed!", "task result", taskAddr, "error", err) // Handle the error gracefully, continue to the next continue } actualThreshold := taskPowerTotal.Quo(operatorPowerTotal).Mul(sdk.NewDec(100)) if err != nil { - ctx.Logger().Error("Failed to update task result statistics", "task result", taskAddr, "error", err) + ctx.Logger().Error("Failed to update task result statistics,Calculation of actualThreshold ratio failed!", "task result", taskAddr, "error", err) // Handle the error gracefully, continue to the next continue } @@ -102,7 +102,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( // Update the taskInfo in the state err = wrapper.keeper.SetTaskInfo(ctx, taskInfo) if err != nil { - ctx.Logger().Error("Failed to update task result statistics", "task result", taskAddr, "error", err) + ctx.Logger().Error("Failed to update task result statistics,SetTaskInfo call failed!", "task result", taskAddr, "error", err) // Handle the error gracefully, continue to the next continue } diff --git a/x/avs/keeper/task.go b/x/avs/keeper/task.go index b3ecac520..da950d267 100644 --- a/x/avs/keeper/task.go +++ b/x/avs/keeper/task.go @@ -3,6 +3,7 @@ package keeper import ( "bytes" "fmt" + "sort" "strconv" "strings" @@ -251,13 +252,16 @@ func (k *Keeper) SetTaskResultInfo( // check hash taskResponseDigest := crypto.Keccak256Hash(info.TaskResponse) - hashWithoutPrefix := strings.TrimPrefix(taskResponseDigest.String(), "0x") - if hashWithoutPrefix != info.TaskResponseHash { - return errorsmod.Wrap( - types.ErrHashValue, - "SetTaskResultInfo: task response is nil", - ) + if info.TaskResponseHash != "" { + hashWithoutPrefix := strings.TrimPrefix(taskResponseDigest.String(), "0x") + if hashWithoutPrefix != info.TaskResponseHash { + return errorsmod.Wrap( + types.ErrHashValue, + "SetTaskResultInfo: task response is nil", + ) + } } + // TODO :check taskID // resp, err := types.UnmarshalTaskResponse(info.TaskResponse) // if err != nil || info.TaskId != resp.TaskID { @@ -344,6 +348,14 @@ func (k Keeper) GroupTasksByIDAndAddress(tasks []types.TaskResultInfo) map[strin key := task.TaskContractAddress + "_" + strconv.FormatUint(task.TaskId, 10) taskMap[key] = append(taskMap[key], task) } + + // Sort tasks in each group by OperatorAddress + for key, taskGroup := range taskMap { + sort.Slice(taskGroup, func(i, j int) bool { + return taskGroup[i].OperatorAddress < taskGroup[j].OperatorAddress + }) + taskMap[key] = taskGroup + } return taskMap } diff --git a/x/avs/types/types.go b/x/avs/types/types.go index e6fd76323..89535c3f0 100644 --- a/x/avs/types/types.go +++ b/x/avs/types/types.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "math/big" + "sort" "strings" "github.com/ethereum/go-ethereum/accounts/abi" @@ -168,16 +169,13 @@ func Difference(a, b []string) []string { } } - // Calculate the final size for the different slice - finalSize := len(different) + len(diffMap) - - // Pre-allocate the different slice with the final size - different = make([]string, 0, finalSize) - // Add remaining elements from the map to different for item := range diffMap { different = append(different, item) } + // Sort the different slice + sort.Strings(different) + return different }