diff --git a/process/logsevents/logsMerger.go b/process/logsevents/logsMerger.go index 3c488a00..7a8e4a38 100644 --- a/process/logsevents/logsMerger.go +++ b/process/logsevents/logsMerger.go @@ -1,6 +1,8 @@ package logsevents import ( + "sort" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data/transaction" @@ -41,12 +43,26 @@ func (lm *logsMerger) MergeLogEvents(logSource *transaction.ApiLogs, logDestinat return logSource } - eventsHash := make(map[string]struct{}) - - mergedEvents := lm.mergeEvents(eventsHash, logSource) - eventsFromDestination := lm.mergeEvents(eventsHash, logDestination) - - mergedEvents = append(mergedEvents, eventsFromDestination...) + eventMap := make(map[string]*transaction.Events) + allLogs := []*transaction.ApiLogs{logSource, logDestination} + hashes := make([]string, 0) + for _, lg := range allLogs { + for _, ev := range lg.Events { + hash, _ := core.CalculateHash(lm.marshalizer, lm.hasher, ev) + _, found := eventMap[string(hash)] + if found { + continue + } + + eventMap[string(hash)] = ev + hashes = append(hashes, string(hash)) + } + } + sort.Strings(hashes) + mergedEvents := make([]*transaction.Events, 0, len(hashes)) + for _, h := range hashes { + mergedEvents = append(mergedEvents, eventMap[h]) + } return &transaction.ApiLogs{ Address: logSource.Address, @@ -54,26 +70,6 @@ func (lm *logsMerger) MergeLogEvents(logSource *transaction.ApiLogs, logDestinat } } -func (lm *logsMerger) mergeEvents(eventsHash map[string]struct{}, apiLog *transaction.ApiLogs) []*transaction.Events { - events := make([]*transaction.Events, 0) - for _, event := range apiLog.Events { - logHash, err := core.CalculateHash(lm.marshalizer, lm.hasher, event) - if err != nil { - log.Warn("logsMerger.mergeEvents cannot compute event hash", "error", err.Error()) - } - - _, found := eventsHash[string(logHash)] - if found { - continue - } - - eventsHash[string(logHash)] = struct{}{} - events = append(events, event) - } - - return events -} - // IsInterfaceNil returns true if the value under the interface is nil func (lm *logsMerger) IsInterfaceNil() bool { return lm == nil diff --git a/process/logsevents/logsMerger_test.go b/process/logsevents/logsMerger_test.go index 7a70253c..f0905c1d 100644 --- a/process/logsevents/logsMerger_test.go +++ b/process/logsevents/logsMerger_test.go @@ -110,3 +110,50 @@ func TestLogsMerger_MergeLogsAlwaysSameOrder(t *testing.T) { }, }, res.Events) } + +func TestLogsMerger_MergeLogsAlwaysSorted(t *testing.T) { + hasher, _ := hasherFactory.NewHasher("blake2b") + marshalizer, _ := marshalFactory.NewMarshalizer("json") + lp, _ := NewLogsMerger(hasher, marshalizer) + + sourceLog := &transaction.ApiLogs{ + Address: "addr1", + Events: []*transaction.Events{ + { + Data: []byte("data1"), + }, + { + Data: []byte("data2"), + }, + { + Data: []byte("data12"), + }, + { + Data: []byte("data16"), + }, + }, + } + destinationLog := &transaction.ApiLogs{ + Address: "addr1", + Events: []*transaction.Events{ + { + Data: []byte("data3"), + }, + { + Data: []byte("data11"), + }, + { + Data: []byte("data1"), + }, + { + Data: []byte("data112"), + }, + }, + } + + res1 := lp.MergeLogEvents(sourceLog, destinationLog) + res2 := lp.MergeLogEvents(destinationLog, sourceLog) + require.NotEmpty(t, res1, "merged logs should not be empty") + require.NotEmpty(t, res2, "merged logs should not be empty") + require.Equal(t, res1, res2) +}