Skip to content

Commit bd628de

Browse files
authored
Merge pull request #5666 from multiversx/equivalent_messages_filter
Equivalent messages filter on consensus topic
2 parents 8145826 + c9fe2aa commit bd628de

20 files changed

+610
-115
lines changed

cmd/node/config/enableEpochs.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@
287287
# FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch represents the epoch when the fix for the remaining gas in the SaveKeyValue builtin function is enabled
288288
FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch = 3
289289

290+
# EquivalentMessagesEnableEpoch represents the epoch when the equivalent messages are enabled
291+
EquivalentMessagesEnableEpoch = 3
292+
290293
# BLSMultiSignerEnableEpoch represents the activation epoch for different types of BLS multi-signers
291294
BLSMultiSignerEnableEpoch = [
292295
{ EnableEpoch = 0, Type = "no-KOSK" },

common/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,5 +1001,6 @@ const (
10011001
NFTStopCreateFlag core.EnableEpochFlag = "NFTStopCreateFlag"
10021002
FixGasRemainingForSaveKeyValueFlag core.EnableEpochFlag = "FixGasRemainingForSaveKeyValueFlag"
10031003
IsChangeOwnerAddressCrossShardThroughSCFlag core.EnableEpochFlag = "IsChangeOwnerAddressCrossShardThroughSCFlag"
1004+
EquivalentMessagesFlag core.EnableEpochFlag = "EquivalentMessagesFlag"
10041005
// all new flags must be added to createAllFlagsMap method, as part of enableEpochsHandler allFlagsDefined
10051006
)

common/enablers/enableEpochsHandler.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,12 @@ func (handler *enableEpochsHandler) createAllFlagsMap() {
695695
},
696696
activationEpoch: handler.enableEpochsConfig.ChangeOwnerAddressCrossShardThroughSCEnableEpoch,
697697
},
698+
common.EquivalentMessagesFlag: {
699+
isActiveInEpoch: func(epoch uint32) bool {
700+
return epoch >= handler.enableEpochsConfig.EquivalentMessagesEnableEpoch
701+
},
702+
activationEpoch: handler.enableEpochsConfig.EquivalentMessagesEnableEpoch,
703+
},
698704
}
699705
}
700706

common/enablers/enableEpochsHandler_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func createEnableEpochsConfig() config.EnableEpochs {
110110
NFTStopCreateEnableEpoch: 92,
111111
FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch: 93,
112112
ChangeOwnerAddressCrossShardThroughSCEnableEpoch: 94,
113+
EquivalentMessagesEnableEpoch: 95,
113114
}
114115
}
115116

@@ -297,6 +298,7 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) {
297298
require.True(t, handler.IsFlagEnabled(common.NFTStopCreateFlag))
298299
require.True(t, handler.IsFlagEnabled(common.FixGasRemainingForSaveKeyValueFlag))
299300
require.True(t, handler.IsFlagEnabled(common.IsChangeOwnerAddressCrossShardThroughSCFlag))
301+
require.True(t, handler.IsFlagEnabled(common.EquivalentMessagesFlag))
300302
}
301303

302304
func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) {
@@ -407,6 +409,7 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) {
407409
require.Equal(t, cfg.NFTStopCreateEnableEpoch, handler.GetActivationEpoch(common.NFTStopCreateFlag))
408410
require.Equal(t, cfg.ChangeOwnerAddressCrossShardThroughSCEnableEpoch, handler.GetActivationEpoch(common.IsChangeOwnerAddressCrossShardThroughSCFlag))
409411
require.Equal(t, cfg.FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch, handler.GetActivationEpoch(common.FixGasRemainingForSaveKeyValueFlag))
412+
require.Equal(t, cfg.EquivalentMessagesEnableEpoch, handler.GetActivationEpoch(common.EquivalentMessagesFlag))
410413
}
411414

412415
func TestEnableEpochsHandler_IsInterfaceNil(t *testing.T) {

config/epochConfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type EnableEpochs struct {
108108
NFTStopCreateEnableEpoch uint32
109109
ChangeOwnerAddressCrossShardThroughSCEnableEpoch uint32
110110
FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch uint32
111+
EquivalentMessagesEnableEpoch uint32
111112
BLSMultiSignerEnableEpoch []MultiSignerConfig
112113
}
113114

config/tomlConfig_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,9 @@ func TestEnableEpochConfig(t *testing.T) {
857857
# FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch represents the epoch when the fix for the remaining gas in the SaveKeyValue builtin function is enabled
858858
FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch = 91
859859
860+
# EquivalentMessagesEnableEpoch represents the epoch when the equivalent messages are enabled
861+
EquivalentMessagesEnableEpoch = 92
862+
860863
# MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch
861864
MaxNodesChangeEnableEpoch = [
862865
{ EpochEnable = 44, MaxNumNodes = 2169, NodesToShufflePerShard = 80 },
@@ -968,6 +971,7 @@ func TestEnableEpochConfig(t *testing.T) {
968971
NFTStopCreateEnableEpoch: 89,
969972
ChangeOwnerAddressCrossShardThroughSCEnableEpoch: 90,
970973
FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch: 91,
974+
EquivalentMessagesEnableEpoch: 92,
971975
MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{
972976
{
973977
EpochEnable: 44,

consensus/message.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@ func NewConsensusMessage(
4040
InvalidSigners: invalidSigners,
4141
}
4242
}
43+
44+
// EquivalentMessageInfo holds information about an equivalent message
45+
type EquivalentMessageInfo struct {
46+
NumMessages uint64
47+
Validated bool
48+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package mock
2+
3+
import (
4+
"github.com/multiversx/mx-chain-go/consensus"
5+
)
6+
7+
// EquivalentMessagesDebuggerStub -
8+
type EquivalentMessagesDebuggerStub struct {
9+
DisplayEquivalentMessagesStatisticsCalled func(getDataHandler func() map[string]*consensus.EquivalentMessageInfo)
10+
}
11+
12+
// DisplayEquivalentMessagesStatistics -
13+
func (stub *EquivalentMessagesDebuggerStub) DisplayEquivalentMessagesStatistics(getDataHandler func() map[string]*consensus.EquivalentMessageInfo) {
14+
if stub.DisplayEquivalentMessagesStatisticsCalled != nil {
15+
stub.DisplayEquivalentMessagesStatisticsCalled(getDataHandler)
16+
}
17+
}
18+
19+
// IsInterfaceNil -
20+
func (stub *EquivalentMessagesDebuggerStub) IsInterfaceNil() bool {
21+
return stub == nil
22+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package debug
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/multiversx/mx-chain-core-go/display"
7+
"github.com/multiversx/mx-chain-go/consensus"
8+
logger "github.com/multiversx/mx-chain-logger-go"
9+
)
10+
11+
var log = logger.GetOrCreate("debug/equivalentmessages")
12+
13+
type equivalentMessagesDebugger struct {
14+
shouldProcessDataFunc func() bool
15+
}
16+
17+
// NewEquivalentMessagesDebugger returns a new instance of equivalentMessagesDebugger
18+
func NewEquivalentMessagesDebugger() *equivalentMessagesDebugger {
19+
debugger := &equivalentMessagesDebugger{
20+
shouldProcessDataFunc: isLogTrace,
21+
}
22+
23+
return debugger
24+
}
25+
26+
// DisplayEquivalentMessagesStatistics prints all the equivalent messages
27+
func (debugger *equivalentMessagesDebugger) DisplayEquivalentMessagesStatistics(getDataHandler func() map[string]*consensus.EquivalentMessageInfo) {
28+
if !debugger.shouldProcessDataFunc() {
29+
return
30+
}
31+
if getDataHandler == nil {
32+
return
33+
}
34+
35+
dataMap := getDataHandler()
36+
log.Trace(fmt.Sprintf("Equivalent messages statistics for current round\n%s", dataToString(dataMap)))
37+
}
38+
39+
func dataToString(data map[string]*consensus.EquivalentMessageInfo) string {
40+
header := []string{
41+
"Block header hash",
42+
"Equivalent messages received",
43+
}
44+
45+
lines := make([]*display.LineData, 0, len(data))
46+
idx := 0
47+
for hash, info := range data {
48+
horizontalLineAfter := idx == len(data)
49+
line := []string{
50+
hash,
51+
fmt.Sprintf("%d", info.NumMessages),
52+
}
53+
lines = append(lines, display.NewLineData(horizontalLineAfter, line))
54+
idx++
55+
}
56+
57+
table, err := display.CreateTableString(header, lines)
58+
if err != nil {
59+
return "error creating p2p stats table: " + err.Error()
60+
}
61+
62+
return table
63+
}
64+
65+
func isLogTrace() bool {
66+
return log.GetLevel() == logger.LogTrace
67+
}
68+
69+
// IsInterfaceNil returns true if there is no value under the interface
70+
func (debugger *equivalentMessagesDebugger) IsInterfaceNil() bool {
71+
return debugger == nil
72+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package debug
2+
3+
import (
4+
"testing"
5+
6+
"github.com/multiversx/mx-chain-go/consensus"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestNewEquivalentMessagesDebugger_IsInterfaceNil(t *testing.T) {
11+
t.Parallel()
12+
13+
var debugger *equivalentMessagesDebugger
14+
require.True(t, debugger.IsInterfaceNil())
15+
16+
debugger = NewEquivalentMessagesDebugger()
17+
require.False(t, debugger.IsInterfaceNil())
18+
}
19+
20+
func TestEquivalentMessagesDebugger_DisplayEquivalentMessagesStatistics(t *testing.T) {
21+
t.Parallel()
22+
23+
t.Run("log level not trace should early exit", func(t *testing.T) {
24+
t.Parallel()
25+
26+
defer func() {
27+
r := recover()
28+
if r != nil {
29+
require.Fail(t, "should have not panicked")
30+
}
31+
}()
32+
33+
debugger := NewEquivalentMessagesDebugger()
34+
debugger.DisplayEquivalentMessagesStatistics(func() map[string]*consensus.EquivalentMessageInfo {
35+
return make(map[string]*consensus.EquivalentMessageInfo)
36+
})
37+
})
38+
t.Run("nil get data handler should early exit", func(t *testing.T) {
39+
t.Parallel()
40+
41+
defer func() {
42+
r := recover()
43+
if r != nil {
44+
require.Fail(t, "should have not panicked")
45+
}
46+
}()
47+
48+
debugger := NewEquivalentMessagesDebugger()
49+
debugger.shouldProcessDataFunc = func() bool {
50+
return true
51+
}
52+
53+
debugger.DisplayEquivalentMessagesStatistics(nil)
54+
})
55+
t.Run("should work", func(t *testing.T) {
56+
t.Parallel()
57+
58+
defer func() {
59+
r := recover()
60+
if r != nil {
61+
require.Fail(t, "should have not panicked")
62+
}
63+
}()
64+
65+
debugger := NewEquivalentMessagesDebugger()
66+
debugger.shouldProcessDataFunc = func() bool {
67+
return true
68+
}
69+
70+
debugger.DisplayEquivalentMessagesStatistics(func() map[string]*consensus.EquivalentMessageInfo {
71+
return map[string]*consensus.EquivalentMessageInfo{
72+
"hash1": {NumMessages: 1, Validated: true},
73+
"hash2": {NumMessages: 2, Validated: true},
74+
"hash3": {NumMessages: 3, Validated: true},
75+
"hash4": {NumMessages: 4, Validated: true},
76+
}
77+
})
78+
79+
})
80+
}

0 commit comments

Comments
 (0)