Skip to content

Commit 25e7805

Browse files
authored
Merge branch 'feat/supernova-async-exec' into cross-shard-execution-analysis
2 parents b58fc8a + 395b553 commit 25e7805

246 files changed

Lines changed: 8383 additions & 1581 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/gin/webServer.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ import (
1212
"github.com/gin-gonic/gin"
1313
"github.com/multiversx/mx-chain-core-go/core/check"
1414
"github.com/multiversx/mx-chain-core-go/marshal"
15+
logger "github.com/multiversx/mx-chain-logger-go"
16+
"github.com/prometheus/client_golang/prometheus/promhttp"
17+
1518
"github.com/multiversx/mx-chain-go/api/errors"
1619
"github.com/multiversx/mx-chain-go/api/groups"
1720
"github.com/multiversx/mx-chain-go/api/middleware"
1821
"github.com/multiversx/mx-chain-go/api/shared"
1922
"github.com/multiversx/mx-chain-go/config"
2023
"github.com/multiversx/mx-chain-go/facade"
21-
logger "github.com/multiversx/mx-chain-logger-go"
22-
"github.com/prometheus/client_golang/prometheus/promhttp"
2324
)
2425

2526
var log = logger.GetOrCreate("api/gin")
2627

2728
const prometheusMetricsRoute = "/debug/metrics/prometheus"
29+
const readHeaderTimeout = 10 * time.Second
2830

2931
// ArgsNewWebServer holds the arguments needed to create a new instance of webServer
3032
type ArgsNewWebServer struct {
@@ -126,7 +128,11 @@ func (ws *webServer) StartHttpServer() error {
126128

127129
ws.registerRoutes(engine)
128130

129-
server := &http.Server{Addr: ws.facade.RestApiInterface(), Handler: engine}
131+
server := &http.Server{
132+
Addr: ws.facade.RestApiInterface(),
133+
Handler: engine,
134+
ReadHeaderTimeout: readHeaderTimeout,
135+
}
130136
log.Debug("creating gin web sever", "interface", ws.facade.RestApiInterface())
131137
ws.httpServer, err = NewHttpServer(server)
132138
if err != nil {

api/groups/networkGroup.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const (
2323
economicsPath = "/economics"
2424
enableEpochsPath = "/enable-epochs"
2525
enableEpochsV2Path = "/enable-epochs-v2"
26+
enableRoundsPath = "/enable-rounds"
2627
getESDTsPath = "/esdts"
2728
getFFTsPath = "/esdt/fungible-tokens"
2829
getSFTsPath = "/esdt/semi-fungible-tokens"
@@ -105,6 +106,11 @@ func NewNetworkGroup(facade networkFacadeHandler) (*networkGroup, error) {
105106
Method: http.MethodGet,
106107
Handler: ng.getEnableEpochsV2,
107108
},
109+
{
110+
Path: enableRoundsPath,
111+
Method: http.MethodGet,
112+
Handler: ng.getEnableRounds,
113+
},
108114
{
109115
Path: getESDTsPath,
110116
Method: http.MethodGet,
@@ -230,6 +236,20 @@ func (ng *networkGroup) getEnableEpochsV2(c *gin.Context) {
230236
)
231237
}
232238

239+
// getEnableRounds returns metrics related to the activation rounds of the network
240+
func (ng *networkGroup) getEnableRounds(c *gin.Context) {
241+
enableRoundsMetrics := ng.getFacade().StatusMetrics().EnableRoundsMetrics()
242+
243+
c.JSON(
244+
http.StatusOK,
245+
shared.GenericAPIResponse{
246+
Data: gin.H{"enableRounds": enableRoundsMetrics},
247+
Error: "",
248+
Code: shared.ReturnCodeSuccess,
249+
},
250+
)
251+
}
252+
233253
// getNetworkStatus returns metrics related to the network status (shard specific)
234254
func (ng *networkGroup) getNetworkStatus(c *gin.Context) {
235255
networkMetrics, err := ng.getFacade().StatusMetrics().NetworkMetrics()

api/groups/networkGroup_test.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type testStatusMetricsHandler interface {
3535
}
3636

3737
func createNetworkStatusMetrics() testStatusMetricsHandler {
38-
sm, _ := statusHandler.NewStatusMetrics(&enableEpochsHandlerMock.EnableEpochsHandlerStub{})
38+
sm, _ := statusHandler.NewStatusMetrics(&enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &testscommon.EnableRoundsHandlerStub{})
3939
return sm
4040
}
4141

@@ -654,7 +654,7 @@ func TestGetEnableEpochsV2_ShouldWork(t *testing.T) {
654654
GetAllEnableEpochsCalled: func() map[string]uint32 {
655655
return allEpochsMap
656656
},
657-
})
657+
}, &testscommon.EnableRoundsHandlerStub{})
658658

659659
facade := mock.FacadeStub{}
660660
facade.StatusMetricsHandler = func() external.StatusMetricsHandler {
@@ -679,6 +679,43 @@ func TestGetEnableEpochsV2_ShouldWork(t *testing.T) {
679679
assert.True(t, keyAndValueFoundInResponse)
680680
}
681681

682+
func TestGetEnableRounds_ShouldWork(t *testing.T) {
683+
t.Parallel()
684+
685+
expectedRounds := map[string]uint64{
686+
"round1": 100,
687+
"round2": 200,
688+
}
689+
690+
facade := mock.FacadeStub{
691+
StatusMetricsHandler: func() external.StatusMetricsHandler {
692+
return &testscommon.StatusMetricsStub{
693+
EnableRoundsMetricsCalled: func() map[string]uint64 {
694+
return expectedRounds
695+
},
696+
}
697+
},
698+
}
699+
700+
networkGroup, err := groups.NewNetworkGroup(&facade)
701+
require.NoError(t, err)
702+
703+
ws := startWebServer(networkGroup, "network", getNetworkRoutesConfig())
704+
705+
req, _ := http.NewRequest("GET", "/network/enable-rounds", nil)
706+
resp := httptest.NewRecorder()
707+
ws.ServeHTTP(resp, req)
708+
709+
respBytes, _ := io.ReadAll(resp.Body)
710+
respStr := string(respBytes)
711+
assert.Equal(t, http.StatusOK, resp.Code)
712+
713+
keyAndValueFoundInResponse := strings.Contains(respStr, "round1") && strings.Contains(respStr, "100") &&
714+
strings.Contains(respStr, "round2") && strings.Contains(respStr, "200")
715+
assert.True(t, keyAndValueFoundInResponse)
716+
assert.True(t, strings.Contains(respStr, "enableRounds"))
717+
}
718+
682719
func TestGetESDTTotalSupply_InternalError(t *testing.T) {
683720
t.Parallel()
684721

@@ -1108,6 +1145,7 @@ func getNetworkRoutesConfig() config.ApiRoutesConfig {
11081145
{Name: "/genesis-balances", Open: true},
11091146
{Name: "/ratings", Open: true},
11101147
{Name: "/gas-configs", Open: true},
1148+
{Name: "/enable-rounds", Open: true},
11111149
},
11121150
},
11131151
},

api/groups/nodeGroup_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type testNodeStatusMetricsHandler interface {
3636
}
3737

3838
func createNodeStatusMetrics() testNodeStatusMetricsHandler {
39-
sm, _ := statusHandler.NewStatusMetrics(&enableEpochsHandlerMock.EnableEpochsHandlerStub{})
39+
sm, _ := statusHandler.NewStatusMetrics(&enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &testscommon.EnableRoundsHandlerStub{})
4040
return sm
4141
}
4242

cmd/node/config/api.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@
134134
# /network/enable-epochs-v2 will return metrics related to activation epochs in the same format as in toml
135135
{ Name = "/enable-epochs-v2", Open = true },
136136

137+
# /network/enable-rounds will return metrics related to activation rounds
138+
{ Name = "/enable-rounds", Open = true },
139+
137140
# /network/esdts will return all the issued esdts on the protocol
138141
{ Name = "/esdts", Open = true },
139142

cmd/node/config/config.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
# Make sure that this is greater than the unbonding period!
3939
SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing
4040

41+
# MaxProposalNonceGap defines the maximum gap allowed between the highest finalized nonce and lowest proposed nonce
42+
MaxProposalNonceGap = 50
43+
4144
# ChainParametersByEpoch defines chain operation configurable values that can be modified based on epochs
4245
ChainParametersByEpoch = [
4346
{ EnableEpoch = 0, RoundDuration = 6000, RoundsPerEpoch = 200, MinRoundsBetweenEpochs = 20, ShardConsensusGroupSize = 7, ShardMinNumNodes = 10, MetachainConsensusGroupSize = 10, MetachainMinNumNodes = 10, Hysteresis = 0.2, Adaptivity = false, Offset = 0 },
@@ -514,6 +517,12 @@
514517
SelectionGasBandwidthIncreaseScheduledPercent = 260
515518
SelectionGasRequested = 10_000_000_000
516519

520+
[AOTSelection]
521+
# Ahead-of-Time transaction selection - pre-selects transactions before consensus round
522+
Enabled = true
523+
CacheSize = 10 # Number of pre-selection results to cache
524+
SelectionTimeoutMs = 150 # Max time for AOT selection in milliseconds
525+
517526
[TrieNodesChunksDataPool]
518527
Name = "TrieNodesDataPool"
519528
Capacity = 400
@@ -889,6 +898,7 @@
889898
[BlockSizeThrottleConfig]
890899
MinSizeInBytes = 104857 # 104857 is 10% from 1MB
891900
MaxSizeInBytes = 943718 # 943718 is 90% from 1MB
901+
MaxExecResSizeInBytes = 104857 # 104857 is 10% from 1MB
892902

893903
[VirtualMachine]
894904
[VirtualMachine.Execution]
@@ -1176,6 +1186,10 @@
11761186
CacheSpanInSec = 30
11771187
CacheExpiryInSec = 30
11781188

1189+
[DirectSentTransactions]
1190+
CacheSpanInSec = 30
1191+
CacheExpiryInSec = 30
1192+
11791193
[ExecutionResultInclusionEstimator]
11801194
# Safety margin = 110 -> 110% -> 10% buffer
11811195
SafetyMargin = 110

common/consensus/common.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package consensus
2+
3+
import (
4+
"github.com/multiversx/mx-chain-core-go/core/check"
5+
"github.com/multiversx/mx-chain-go/consensus"
6+
logger "github.com/multiversx/mx-chain-logger-go"
7+
)
8+
9+
var log = logger.GetOrCreate("common/consensus")
10+
11+
// ShouldConsiderSelfKeyInConsensus returns true if current machine is the main one, or it is a backup machine but the main
12+
// machine failed
13+
func ShouldConsiderSelfKeyInConsensus(redundancyHandler consensus.NodeRedundancyHandler) bool {
14+
if check.IfNil(redundancyHandler) {
15+
log.Warn("redundancy handler is nil")
16+
return false
17+
}
18+
19+
isMainMachine := !redundancyHandler.IsRedundancyNode()
20+
if isMainMachine {
21+
return true
22+
}
23+
return !redundancyHandler.IsMainMachineActive()
24+
}

common/consensus/common_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package consensus_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/multiversx/mx-chain-go/common/consensus"
7+
consensusMock "github.com/multiversx/mx-chain-go/consensus/mock"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func Test_ShouldConsiderSelfKeyInConsensus(t *testing.T) {
12+
t.Parallel()
13+
14+
// nil handler
15+
assert.False(t, consensus.ShouldConsiderSelfKeyInConsensus(nil))
16+
17+
// main machine
18+
assert.True(t, consensus.ShouldConsiderSelfKeyInConsensus(
19+
&consensusMock.NodeRedundancyHandlerStub{
20+
IsRedundancyNodeCalled: func() bool { return false },
21+
},
22+
))
23+
24+
// backup with active main
25+
assert.False(t, consensus.ShouldConsiderSelfKeyInConsensus(
26+
&consensusMock.NodeRedundancyHandlerStub{
27+
IsRedundancyNodeCalled: func() bool { return true },
28+
IsMainMachineActiveCalled: func() bool { return true },
29+
},
30+
))
31+
32+
// backup with inactive main
33+
assert.True(t, consensus.ShouldConsiderSelfKeyInConsensus(
34+
&consensusMock.NodeRedundancyHandlerStub{
35+
IsRedundancyNodeCalled: func() bool { return true },
36+
IsMainMachineActiveCalled: func() bool { return false },
37+
},
38+
))
39+
}

common/dtos.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,9 @@ type AuctionListValidatorAPIResponse struct {
110110
QualifiedTopUp string `json:"qualifiedTopUp"`
111111
Nodes []*AuctionNode `json:"nodes"`
112112
}
113+
114+
// LastExecutionResultForInclusion is a lightweight summary of the last notarized execution result EIE requires.
115+
type LastExecutionResultForInclusion struct {
116+
NotarizedInRound uint64
117+
ProposedInRound uint64
118+
}

common/enablers/enableRoundsHandler.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,16 @@ func (handler *enableRoundsHandler) GetActivationRound(flag common.EnableRoundFl
170170
return fh.activationRound
171171
}
172172

173+
// GetAllEnableRounds returns a map of all enable round flags with their activation rounds
174+
func (handler *enableRoundsHandler) GetAllEnableRounds() map[string]uint64 {
175+
result := make(map[string]uint64, len(handler.allFlagsDefined))
176+
for flag, flagHandler := range handler.allFlagsDefined {
177+
result[string(flag)] = flagHandler.activationRound
178+
}
179+
180+
return result
181+
}
182+
173183
// IsInterfaceNil returns true if there is no value under the interface
174184
func (handler *enableRoundsHandler) IsInterfaceNil() bool {
175185
return handler == nil

0 commit comments

Comments
 (0)