Skip to content

Commit 8a8e169

Browse files
authored
Merge branch 'feat/supernova-async-exec' into cross-shard-execution-analysis
2 parents c0d71a4 + d3fde09 commit 8a8e169

220 files changed

Lines changed: 5542 additions & 2757 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.

cmd/node/config/config.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,10 @@
574574
Type = "SizeLRU"
575575
SizeInBytes = 104857600 # 100MB
576576

577+
[HeaderBodyCacheConfig]
578+
Capacity = 1000
579+
580+
577581
#PublicKeyPeerId represents the main cache used to map MultiversX block signing public keys to their associated peer id's.
578582
[PublicKeyPeerId]
579583
Name = "PublicKeyPeerId"

cmd/termui/presenter/chainInfoGetters.go

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ func (psh *PresenterStatusHandler) GetNonce() uint64 {
1313
return psh.getFromCacheAsUint64(common.MetricNonce)
1414
}
1515

16+
// GetLastExecutedNonce will return current last executed nonce of node
17+
func (psh *PresenterStatusHandler) GetLastExecutedNonce() uint64 {
18+
return psh.getFromCacheAsUint64(common.MetricLastExecutedNonce)
19+
}
20+
21+
// GetProposedNonce will return current proposed nonce of node
22+
func (psh *PresenterStatusHandler) GetProposedNonce() uint64 {
23+
return psh.getFromCacheAsUint64(common.MetricProposedNonce)
24+
}
25+
1626
// GetIsSyncing will return state of the node
1727
func (psh *PresenterStatusHandler) GetIsSyncing() uint64 {
1828
return psh.getFromCacheAsUint64(common.MetricIsSyncing)
@@ -72,25 +82,14 @@ func (psh *PresenterStatusHandler) CalculateTimeToSynchronize(numMillisecondsRef
7282

7383
currentSynchronizedRound := psh.GetSynchronizedRound()
7484

75-
numSynchronizationSpeedHistory := len(psh.synchronizationSpeedHistory)
76-
77-
sum := uint64(0)
78-
for i := 0; i < len(psh.synchronizationSpeedHistory); i++ {
79-
sum += psh.synchronizationSpeedHistory[i]
80-
}
81-
82-
speed := float64(0)
83-
if numSynchronizationSpeedHistory > 0 {
84-
speed = float64(sum*1000) / float64(numSynchronizationSpeedHistory*numMillisecondsRefreshTime)
85-
}
86-
85+
speed := psh.calculateSpeedFromSpeedHistory(numMillisecondsRefreshTime)
8786
currentRound := psh.GetCurrentRound()
8887
if currentRound < currentSynchronizedRound || speed == 0 {
89-
return ""
88+
return "Estimating..."
9089
}
9190

9291
remainingRoundsToSynchronize := currentRound - currentSynchronizedRound
93-
timeEstimationSeconds := float64(remainingRoundsToSynchronize) / speed
92+
timeEstimationSeconds := float64(remainingRoundsToSynchronize) / float64(speed)
9493
remainingTime := core.SecondsToHourMinSec(int(timeEstimationSeconds))
9594

9695
return remainingTime
@@ -100,47 +99,37 @@ func (psh *PresenterStatusHandler) CalculateTimeToSynchronize(numMillisecondsRef
10099
// how many blocks per second are synchronized
101100
func (psh *PresenterStatusHandler) CalculateSynchronizationSpeed(numMillisecondsRefreshTime int) uint64 {
102101
currentSynchronizedRound := psh.GetSynchronizedRound()
103-
if psh.oldRound == 0 {
104-
psh.oldRound = currentSynchronizedRound
105-
return 0
106-
}
107-
108-
roundsPerSecond := int64(currentSynchronizedRound - psh.oldRound)
109-
if roundsPerSecond < 0 {
110-
roundsPerSecond = 0
111-
}
112102

113103
if len(psh.synchronizationSpeedHistory) >= maxSpeedHistorySaved {
114-
psh.synchronizationSpeedHistory = psh.synchronizationSpeedHistory[1:len(psh.synchronizationSpeedHistory)]
104+
psh.synchronizationSpeedHistory = psh.synchronizationSpeedHistory[1:]
115105
}
116-
psh.synchronizationSpeedHistory = append(psh.synchronizationSpeedHistory, uint64(roundsPerSecond))
106+
psh.synchronizationSpeedHistory = append(psh.synchronizationSpeedHistory, currentSynchronizedRound)
117107

118-
psh.oldRound = currentSynchronizedRound
108+
speed := psh.calculateSpeedFromSpeedHistory(numMillisecondsRefreshTime)
119109

120-
numSyncedBlocks := uint64(0)
121-
cumulatedTime := uint64(0)
110+
return speed
111+
}
112+
113+
func (psh *PresenterStatusHandler) calculateSpeedFromSpeedHistory(numMillisecondsRefreshTime int) uint64 {
122114
lastIndex := len(psh.synchronizationSpeedHistory) - 1
123-
millisecondsInASecond := uint64(1000)
124-
for {
125-
if lastIndex < 0 {
126-
break
127-
}
128-
if cumulatedTime >= millisecondsInASecond {
129-
break
130-
}
115+
firstIndex := 0
131116

132-
numSyncedBlocks += psh.synchronizationSpeedHistory[lastIndex]
133-
lastIndex--
134-
cumulatedTime += uint64(numMillisecondsRefreshTime)
117+
if lastIndex <= firstIndex {
118+
return 0
135119
}
136-
if cumulatedTime == 0 || numSyncedBlocks == 0 {
120+
121+
numSyncedBlocks := psh.synchronizationSpeedHistory[lastIndex] - psh.synchronizationSpeedHistory[firstIndex]
122+
cumulatedTimeMs := uint64((lastIndex - firstIndex) * numMillisecondsRefreshTime)
123+
124+
if cumulatedTimeMs == 0 || numSyncedBlocks == 0 {
137125
return 0
138126
}
139127

140-
timeAdjustment := float64(millisecondsInASecond) / float64(cumulatedTime)
141-
syncedBlocksAdjustment := timeAdjustment * float64(numSyncedBlocks)
128+
numMillisecondsInASecond := 1000.0
129+
speed := (float64(numSyncedBlocks) / float64(cumulatedTimeMs)) * numMillisecondsInASecond
130+
131+
return uint64(speed)
142132

143-
return uint64(syncedBlocksAdjustment)
144133
}
145134

146135
// GetNumTxProcessed will return number of processed transactions since node starts

cmd/termui/presenter/chainInfoGetters_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,28 @@ func TestPresenterStatusHandler_GetNonce(t *testing.T) {
2222
assert.Equal(t, nonce, result)
2323
}
2424

25+
func TestPresenterStatusHandler_GetLastExecutedNonce(t *testing.T) {
26+
t.Parallel()
27+
28+
nonce := uint64(900)
29+
presenterStatusHandler := NewPresenterStatusHandler()
30+
presenterStatusHandler.SetUInt64Value(common.MetricLastExecutedNonce, nonce)
31+
result := presenterStatusHandler.GetLastExecutedNonce()
32+
33+
assert.Equal(t, nonce, result)
34+
}
35+
36+
func TestPresenterStatusHandler_GetProposedNonce(t *testing.T) {
37+
t.Parallel()
38+
39+
nonce := uint64(1000)
40+
presenterStatusHandler := NewPresenterStatusHandler()
41+
presenterStatusHandler.SetUInt64Value(common.MetricProposedNonce, nonce)
42+
result := presenterStatusHandler.GetProposedNonce()
43+
44+
assert.Equal(t, nonce, result)
45+
}
46+
2547
func TestPresenterStatusHandler_GetIsSyncing(t *testing.T) {
2648
t.Parallel()
2749

@@ -132,7 +154,11 @@ func TestPresenterStatusHandler_CalculateTimeToSynchronize(t *testing.T) {
132154
time.Sleep(time.Second)
133155
presenterStatusHandler.SetUInt64Value(common.MetricSynchronizedRound, currentBlockNonce)
134156
presenterStatusHandler.SetUInt64Value(common.MetricCurrentRound, probableHighestNonce)
135-
presenterStatusHandler.synchronizationSpeedHistory = append(presenterStatusHandler.synchronizationSpeedHistory, synchronizationSpeed)
157+
presenterStatusHandler.synchronizationSpeedHistory = []uint64{
158+
currentBlockNonce,
159+
currentBlockNonce + synchronizationSpeed,
160+
}
161+
136162
synchronizationEstimation := presenterStatusHandler.CalculateTimeToSynchronize(1000)
137163

138164
// Node needs to synchronize 190 blocks and synchronization speed is 10 blocks/s

cmd/termui/view/interface.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type Presenter interface {
2929
GetIsSyncing() uint64
3030
GetTxPoolLoad() uint64
3131
GetNonce() uint64
32+
GetProposedNonce() uint64
33+
GetLastExecutedNonce() uint64
3234
GetProbableHighestNonce() uint64
3335
GetSynchronizedRound() uint64
3436
GetRoundTime() uint64

cmd/termui/view/termuic/termuiRenders/widgetsRender.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,20 @@ func (wr *WidgetsRender) prepareBlockInfo() {
303303
numRows := 10
304304
rows := make([][]string, numRows)
305305

306-
currentBlockHeight := wr.presenter.GetNonce()
306+
currentBlockHeight := wr.presenter.GetProposedNonce()
307307
blockSize := wr.presenter.GetBlockSize()
308-
rows[0] = []string{fmt.Sprintf("Current block height: %d, size: %s", currentBlockHeight, core.ConvertBytes(blockSize))}
308+
lastExecutedNonce := wr.presenter.GetLastExecutedNonce()
309+
lastNotarizedExecutedNonce := wr.presenter.GetNonce()
310+
311+
if currentBlockHeight == 0 {
312+
currentBlockHeight = lastNotarizedExecutedNonce
313+
}
314+
315+
if lastExecutedNonce == 0 {
316+
lastExecutedNonce = currentBlockHeight
317+
}
318+
319+
rows[0] = []string{fmt.Sprintf("Current block height: %d, size: %s, last executed nonce: %d, last notarized executed nonce: %d", currentBlockHeight, core.ConvertBytes(blockSize), lastExecutedNonce, lastNotarizedExecutedNonce)}
309320

310321
numTransactionInBlock := wr.presenter.GetNumTxInBlock()
311322
numMiniBlocks := wr.presenter.GetNumMiniBlocks()

cmd/termui/view/termuic/termuiRenders/widgetsRender_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ func TestWidgetsRender_prepareLogLines(t *testing.T) {
5050

5151
func TestPrepareBlockInfo(t *testing.T) {
5252
presenterStatusHandler := presenter.NewPresenterStatusHandler()
53-
presenterStatusHandler.SetUInt64Value(common.MetricNonce, 42)
53+
presenterStatusHandler.SetUInt64Value(common.MetricNonce, 38)
54+
presenterStatusHandler.SetUInt64Value(common.MetricLastExecutedNonce, 40)
55+
presenterStatusHandler.SetUInt64Value(common.MetricProposedNonce, 42)
5456
presenterStatusHandler.SetUInt64Value(common.MetricMiniBlocksSize, 2000)
5557
presenterStatusHandler.SetUInt64Value(common.MetricHeaderSize, 48)
5658
presenterStatusHandler.SetUInt64Value(common.MetricNumTxInBlock, 5)
@@ -83,7 +85,7 @@ func TestPrepareBlockInfo(t *testing.T) {
8385
require.Len(t, wr.blockInfo.Rows, 10)
8486

8587
// Example: check one row
86-
require.Contains(t, wr.blockInfo.Rows[0][0], fmt.Sprintf("Current block height: %d, size: %s", 42, "2.00 KB"))
88+
require.Contains(t, wr.blockInfo.Rows[0][0], fmt.Sprintf("Current block height: %d, size: %s, last executed nonce: %d, last notarized executed nonce: %d", 42, "2.00 KB", 40, 38))
8789
require.Contains(t, wr.blockInfo.Rows[2][0], "hash")
8890
require.Contains(t, wr.blockInfo.Rows[4][0], "Consensus state: ProposedBlock | Consensus round state: Success")
8991
require.Contains(t, wr.blockInfo.Rows[5][0], "Received proposed block: 0.002000 sec | Received proof: 0.003000 sec")

common/channels.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,16 @@ func CloseKeyValueHolderChan(ch chan core.KeyValueHolder) {
1616
close(ch)
1717
}
1818
}
19+
20+
// EmptyUint64Channel will return the number of reads from the channel
21+
func EmptyUint64Channel(ch chan uint64) int {
22+
nrReads := 0
23+
for {
24+
select {
25+
case <-ch:
26+
nrReads++
27+
default:
28+
return nrReads
29+
}
30+
}
31+
}

common/channels_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,40 @@ func didTriggerHappen(ch chan struct{}) bool {
3636
return false
3737
}
3838
}
39+
40+
func TestEmptyUint64Channel_EmptyChannel(t *testing.T) {
41+
t.Parallel()
42+
43+
ch := make(chan uint64, 5)
44+
nrReads := EmptyUint64Channel(ch)
45+
46+
require.Equal(t, 0, nrReads)
47+
}
48+
49+
func TestEmptyUint64Channel_ChannelWithValues(t *testing.T) {
50+
t.Parallel()
51+
52+
ch := make(chan uint64, 5)
53+
ch <- 1
54+
ch <- 2
55+
ch <- 3
56+
57+
nrReads := EmptyUint64Channel(ch)
58+
59+
require.Equal(t, 3, nrReads)
60+
require.Equal(t, 0, len(ch))
61+
}
62+
63+
func TestEmptyUint64Channel_FullChannel(t *testing.T) {
64+
t.Parallel()
65+
66+
ch := make(chan uint64, 3)
67+
ch <- 10
68+
ch <- 20
69+
ch <- 30
70+
71+
nrReads := EmptyUint64Channel(ch)
72+
73+
require.Equal(t, 3, nrReads)
74+
require.Equal(t, 0, len(ch))
75+
}

common/common.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -603,51 +603,3 @@ func GetMiniBlockHeadersFromExecResult(header data.HeaderHandler) ([]data.MiniBl
603603

604604
return mbHeaderHandlers, nil
605605
}
606-
607-
// GetAccumulatedFeesInEpoch returns the accumulated fees in epoch from the header
608-
func GetAccumulatedFeesInEpoch(header data.HeaderHandler) *big.Int {
609-
if check.IfNil(header) {
610-
return big.NewInt(0)
611-
}
612-
613-
if !header.IsHeaderV3() {
614-
metaHeader, ok := header.(data.MetaHeaderHandler)
615-
if !ok {
616-
return big.NewInt(0)
617-
}
618-
619-
return metaHeader.GetAccumulatedFeesInEpoch()
620-
}
621-
622-
metaExecutionResult, ok := header.GetLastExecutionResultHandler().(data.LastMetaExecutionResultHandler)
623-
if !ok {
624-
log.Warn("GetAccumulatedFeesInEpoch cannot cast last execution result handler to data.LastMetaExecutionResultHandler")
625-
return big.NewInt(0)
626-
}
627-
628-
return metaExecutionResult.GetExecutionResultHandler().GetAccumulatedFeesInEpoch()
629-
}
630-
631-
// GetDeveloperFeesInEpoch returns the developer fees in epoch from the header
632-
func GetDeveloperFeesInEpoch(header data.HeaderHandler) *big.Int {
633-
if check.IfNil(header) {
634-
return big.NewInt(0)
635-
}
636-
637-
if !header.IsHeaderV3() {
638-
metaHeader, ok := header.(data.MetaHeaderHandler)
639-
if !ok {
640-
return big.NewInt(0)
641-
}
642-
643-
return metaHeader.GetDevFeesInEpoch()
644-
}
645-
646-
metaExecutionResult, ok := header.GetLastExecutionResultHandler().(data.LastMetaExecutionResultHandler)
647-
if !ok {
648-
log.Warn("GetDeveloperFeesInEpoch cannot cast last execution result handler to data.LastMetaExecutionResultHandler")
649-
return big.NewInt(0)
650-
}
651-
652-
return metaExecutionResult.GetExecutionResultHandler().GetDevFeesInEpoch()
653-
}

0 commit comments

Comments
 (0)