Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trie storage statistics component #5401

Merged
merged 45 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b509c81
storage statistics component in storage package
ssd04 Jul 5, 2023
94db95c
addapt storage statistics component in statusCoreComponents
ssd04 Jul 5, 2023
bdcb008
Revert "addapt storage statistics component in statusCoreComponents"
ssd04 Jul 5, 2023
4e02971
use stats component in trie storage manager
ssd04 Jul 6, 2023
5ba1393
refactor trie statistics component
ssd04 Jul 6, 2023
1be0bd0
update storer with stats interface
ssd04 Jul 7, 2023
1a7db42
fix trie package tests
ssd04 Jul 7, 2023
2471b82
refactor to cast storagemanager in constructor
ssd04 Jul 14, 2023
261c492
fix epoch start unit tests
ssd04 Jul 17, 2023
088a9ac
Merge branch 'rc/v1.6.0' into trie-storage-statistics-component
ssd04 Jul 17, 2023
1b5b5de
fix test in epochstart and integration tests
ssd04 Jul 17, 2023
68cba11
add missing comments
ssd04 Jul 18, 2023
a352567
fix benchmarks integration test
ssd04 Jul 18, 2023
c990e1d
fix linter issue
ssd04 Jul 18, 2023
8aeac06
Merge branch 'rc/v1.6.0' into trie-storage-statistics-component
ssd04 Jul 26, 2023
c0afd2a
fixes after review
ssd04 Aug 7, 2023
8703e00
update trie stub
ssd04 Aug 7, 2023
239929d
Merge branch 'rc/v1.6.0' into trie-storage-statistics-component
ssd04 Sep 4, 2023
7a8fbb4
fix unit tests after merge
ssd04 Sep 4, 2023
c646309
move state stats collector in common
ssd04 Sep 6, 2023
dc3b665
Merge branch 'rc/v1.6.0' into trie-storage-statistics-component
ssd04 Oct 5, 2023
d8e86ed
cleanup trie stats handler
ssd04 Oct 6, 2023
185ea39
separate stats for sync and snapshot
ssd04 Oct 9, 2023
082a009
use atomic map from sync package
ssd04 Oct 10, 2023
f6dc8ed
renamings and comments + fix unit tests
ssd04 Oct 10, 2023
1caef49
fix unit tests - epochstart boostrap and factory
ssd04 Oct 10, 2023
3f566ec
fix integration tests
ssd04 Oct 10, 2023
aa16716
more unit tests + remove old code
ssd04 Oct 10, 2023
77f1f4a
snapshot manager stats
ssd04 Oct 10, 2023
20c0b03
fixes after review
ssd04 Oct 25, 2023
08225bd
fix test
ssd04 Oct 25, 2023
1278c3b
remove trie sync statistics
ssd04 Oct 25, 2023
55b9a70
remove unused code
ssd04 Oct 25, 2023
020f987
fix mutex usage
ssd04 Oct 25, 2023
d45437b
Merge branch 'rc/v1.6.0' into trie-storage-statistics-component
ssd04 Oct 26, 2023
9593d18
Merge branch 'rc/v1.7.0' into trie-storage-statistics-component
ssd04 Oct 26, 2023
ee9c8b6
revert changes from d45437b
ssd04 Oct 26, 2023
a444c20
fix unit test
ssd04 Oct 26, 2023
343e7c8
Merge branch 'rc/v1.7.0' into trie-storage-statistics-component
ssd04 Oct 30, 2023
2b19dd3
update stats return format
ssd04 Oct 30, 2023
97ad360
revert additional changes from 343e7c8
ssd04 Oct 30, 2023
63b2a82
Merge branch 'rc/v1.7.0' into trie-storage-statistics-component
ssd04 Nov 2, 2023
6a4be57
fix integration tests
ssd04 Nov 3, 2023
c192ba4
fix hardfork integration test
ssd04 Nov 3, 2023
d2f3f82
fix create prunning storer maps epoch
ssd04 Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions common/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Trie interface {
VerifyProof(rootHash []byte, key []byte, proof [][]byte) (bool, error)
GetStorageManager() StorageManager
IsMigratedToLatestVersion() (bool, error)
GetStorageStats() string
Close() error
IsInterfaceNil() bool
}
Expand Down Expand Up @@ -120,6 +121,7 @@ type StorageManager interface {
type TrieStorageInteractor interface {
BaseStorer
GetIdentifier() string
GetStateStatsHandler() StateStatisticsHandler
}

// BaseStorer define the base methods needed for a storer
Expand Down Expand Up @@ -218,6 +220,19 @@ type TriesStatisticsCollector interface {
GetNumNodes() uint64
}

// StateStatisticsHandler defines the behaviour of a storage statistics handler
type StateStatisticsHandler interface {
Reset()
IncrCacheOp()
CacheOp() uint64
IncrPersisterOp()
PersisterOp() uint64
IncrTrieOp()
TrieOp() uint64
ToString() string
IsInterfaceNil() bool
}

// ProcessStatusHandler defines the behavior of a component able to hold the current status of the node and
// able to tell if the node is idle or processing/committing a block
type ProcessStatusHandler interface {
Expand Down
49 changes: 49 additions & 0 deletions common/statistics/disabled/stateStatistics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package disabled

type stateStatistics struct{}

// NewStateStatistics will create a new disabled statistics component
func NewStateStatistics() *stateStatistics {
return &stateStatistics{}
}

// Reset does nothing
func (s *stateStatistics) Reset() {
}

// IncrCacheOp does nothing
func (s *stateStatistics) IncrCacheOp() {
}

// CacheOp returns zero
func (s *stateStatistics) CacheOp() uint64 {
return 0
}

// IncrPersisterOp does nothing
func (s *stateStatistics) IncrPersisterOp() {
}

// PersisterOp returns zero
func (s *stateStatistics) PersisterOp() uint64 {
return 0
}

// IncrTrieOp does nothing
func (s *stateStatistics) IncrTrieOp() {
}

// TrieOp returns zero
func (s *stateStatistics) TrieOp() uint64 {
return 0
}

// ToString returns empty string
func (s *stateStatistics) ToString() string {
return ""
}

// IsInterfaceNil returns true if there is no value under the interface
func (s *stateStatistics) IsInterfaceNil() bool {
return s == nil
}
1 change: 1 addition & 0 deletions common/statistics/disabled/stateStatistics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package disabled
BeniaminDrasovean marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions common/statistics/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ var ErrNilNetworkStatisticsProvider = errors.New("nil network statistics provide

// ErrInvalidRefreshIntervalValue signals that an invalid value for the refresh interval was provided
var ErrInvalidRefreshIntervalValue = errors.New("invalid refresh interval value")

// ErrNilStateStatsHandler signals that a nil state statistics handler was provided
var ErrNilStateStatsHandler = errors.New("nil state statistics handler")
71 changes: 71 additions & 0 deletions common/statistics/stateStatistics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package statistics

import (
"fmt"
"strings"
"sync/atomic"
)

type stateStatistics struct {
numCache uint64
numPersister uint64
numTrie uint64
}

// NewStateStatistics returns a structure able to collect statistics for state
func NewStateStatistics() *stateStatistics {
return &stateStatistics{}
}

// Reset will reset the contained values to 0
func (ss *stateStatistics) Reset() {
atomic.StoreUint64(&ss.numCache, 0)
atomic.StoreUint64(&ss.numPersister, 0)
atomic.StoreUint64(&ss.numTrie, 0)
}

// IncrCacheOp will increment cache counter
func (ss *stateStatistics) IncrCacheOp() {
atomic.AddUint64(&ss.numCache, 1)
}

// CacheOp returns the number of cached operations
func (ss *stateStatistics) CacheOp() uint64 {
return atomic.LoadUint64(&ss.numCache)
}

// IncrPersisterOp will increment persister counter
func (ss *stateStatistics) IncrPersisterOp() {
atomic.AddUint64(&ss.numPersister, 1)
}

// PersisterOp returns the number of persister operations
func (ss *stateStatistics) PersisterOp() uint64 {
return atomic.LoadUint64(&ss.numPersister)
}

// IncrTrieOp will increment trie counter
func (ss *stateStatistics) IncrTrieOp() {
atomic.AddUint64(&ss.numTrie, 1)
}

// TrieOp returns the number of trie operations
func (ss *stateStatistics) TrieOp() uint64 {
return atomic.LoadUint64(&ss.numTrie)
}

// ToString returns collected statistics as string
func (ss *stateStatistics) ToString() string {
stats := make([]string, 0)

stats = append(stats, fmt.Sprintf("num cache op = %v", atomic.LoadUint64(&ss.numCache)))
stats = append(stats, fmt.Sprintf("num persister op = %v", atomic.LoadUint64(&ss.numPersister)))
stats = append(stats, fmt.Sprintf("max trie op = %v", atomic.LoadUint64(&ss.numTrie)))

return strings.Join(stats, " ")
}

// IsInterfaceNil returns true if there is no value under the interface
func (ss *stateStatistics) IsInterfaceNil() bool {
return ss == nil
}
121 changes: 121 additions & 0 deletions common/statistics/stateStatistics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package statistics

import (
"fmt"
"sync"
"testing"

"github.com/multiversx/mx-chain-core-go/core/check"
"github.com/stretchr/testify/assert"
)

func TestNewStateStatistics_ShouldWork(t *testing.T) {
t.Parallel()

ss := NewStateStatistics()

assert.False(t, check.IfNil(ss))
}

func TestStateStatistics_Operations(t *testing.T) {
t.Parallel()

t.Run("trie operations", func(t *testing.T) {
t.Parallel()

ss := NewStateStatistics()

assert.Equal(t, uint64(0), ss.TrieOp())

ss.IncrTrieOp()
ss.IncrTrieOp()
assert.Equal(t, uint64(2), ss.TrieOp())

ss.IncrTrieOp()
assert.Equal(t, uint64(3), ss.TrieOp())

ss.Reset()
assert.Equal(t, uint64(0), ss.TrieOp())
})

t.Run("persister operations", func(t *testing.T) {
t.Parallel()

ss := NewStateStatistics()

assert.Equal(t, uint64(0), ss.PersisterOp())

ss.IncrPersisterOp()
ss.IncrPersisterOp()
assert.Equal(t, uint64(2), ss.PersisterOp())

ss.IncrPersisterOp()
assert.Equal(t, uint64(3), ss.PersisterOp())

ss.Reset()
assert.Equal(t, uint64(0), ss.PersisterOp())
})

t.Run("cache operations", func(t *testing.T) {
t.Parallel()

ss := NewStateStatistics()

assert.Equal(t, uint64(0), ss.CacheOp())

ss.IncrCacheOp()
ss.IncrCacheOp()
assert.Equal(t, uint64(2), ss.CacheOp())

ss.IncrCacheOp()
assert.Equal(t, uint64(3), ss.CacheOp())

ss.Reset()
assert.Equal(t, uint64(0), ss.CacheOp())
})
}

func TestStateStatistics_ConcurrenyOperations(t *testing.T) {
t.Parallel()

defer func() {
r := recover()
if r != nil {
assert.Fail(t, fmt.Sprintf("should have not panicked: %v", r))
}
}()

numIterations := 10000

ss := NewStateStatistics()

wg := sync.WaitGroup{}
wg.Add(numIterations)

for i := 0; i < numIterations; i++ {
go func(idx int) {
switch idx % 11 {
case 0:
ss.Reset()
case 1:
ss.IncrCacheOp()
case 2:
ss.IncrPersisterOp()
case 3:
ss.IncrTrieOp()
case 7:
_ = ss.CacheOp()
case 8:
_ = ss.PersisterOp()
case 9:
_ = ss.TrieOp()
case 10:
_ = ss.ToString()
}

wg.Done()
}(i)
}

wg.Wait()
}
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ type StateTriesConfig struct {
PeerStatePruningEnabled bool
MaxStateTrieLevelInMemory uint
MaxPeerTrieLevelInMemory uint
StateStatisticsEnabled bool
}

// TrieStorageManagerConfig will hold config information about trie storage manager
Expand Down
1 change: 1 addition & 0 deletions dataRetriever/factory/storageRequestersContainer/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ type FactoryArgs struct {
ManualEpochStartNotifier dataRetriever.ManualEpochStartNotifier
ChanGracefullyClose chan endProcess.ArgEndProcess
EnableEpochsHandler common.EnableEpochsHandler
StateStatsHandler common.StateStatisticsHandler
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
"github.com/multiversx/mx-chain-core-go/marshal"
"github.com/multiversx/mx-chain-go/common"
"github.com/multiversx/mx-chain-go/common/disabled"
"github.com/multiversx/mx-chain-go/common/statistics"
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/dataRetriever"
disabledRequesters "github.com/multiversx/mx-chain-go/dataRetriever/requestHandlers/requesters/disabled"
"github.com/multiversx/mx-chain-go/dataRetriever/storageRequesters"
storagerequesters "github.com/multiversx/mx-chain-go/dataRetriever/storageRequesters"
"github.com/multiversx/mx-chain-go/errors"
"github.com/multiversx/mx-chain-go/p2p"
"github.com/multiversx/mx-chain-go/process/factory"
Expand All @@ -37,6 +38,7 @@ type baseRequestersContainerFactory struct {
dataPacker dataRetriever.DataPacker
manualEpochStartNotifier dataRetriever.ManualEpochStartNotifier
enableEpochsHandler common.EnableEpochsHandler
stateStatsHandler common.StateStatisticsHandler
chanGracefullyClose chan endProcess.ArgEndProcess
generalConfig config.Config
shardIDForTries uint32
Expand Down Expand Up @@ -76,6 +78,9 @@ func (brcf *baseRequestersContainerFactory) checkParams() error {
if check.IfNil(brcf.enableEpochsHandler) {
return errors.ErrNilEnableEpochsHandler
}
if check.IfNil(brcf.stateStatsHandler) {
return statistics.ErrNilStateStatsHandler
}

return nil
}
Expand Down Expand Up @@ -239,6 +244,7 @@ func (brcf *baseRequestersContainerFactory) newImportDBTrieStorage(
checkpointsStorer storage.Storer,
storageIdentifier dataRetriever.UnitType,
handler common.EnableEpochsHandler,
stateStatsHandler common.StateStatisticsHandler,
) (common.StorageManager, dataRetriever.TrieDataGetter, error) {
pathManager, err := storageFactory.CreatePathManager(
storageFactory.ArgCreatePathManager{
Expand Down Expand Up @@ -271,6 +277,7 @@ func (brcf *baseRequestersContainerFactory) newImportDBTrieStorage(
IdleProvider: disabled.NewProcessStatusHandler(),
Identifier: storageIdentifier.String(),
EnableEpochsHandler: handler,
StatsCollector: stateStatsHandler,
}
return trieFactoryInstance.Create(args)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/multiversx/mx-chain-core-go/core"
"github.com/multiversx/mx-chain-go/dataRetriever"
"github.com/multiversx/mx-chain-go/dataRetriever/factory/containers"
"github.com/multiversx/mx-chain-go/dataRetriever/storageRequesters"
storagerequesters "github.com/multiversx/mx-chain-go/dataRetriever/storageRequesters"
"github.com/multiversx/mx-chain-go/process/factory"
)

Expand Down Expand Up @@ -38,6 +38,7 @@ func NewMetaRequestersContainerFactory(
workingDir: args.WorkingDirectory,
snapshotsEnabled: args.GeneralConfig.StateTriesConfig.SnapshotsEnabled,
enableEpochsHandler: args.EnableEpochsHandler,
stateStatsHandler: args.StateStatsHandler,
}

err := base.checkParams()
Expand Down Expand Up @@ -197,6 +198,7 @@ func (mrcf *metaRequestersContainerFactory) generateTrieNodesRequesters() error
userAccountsCheckpointStorer,
dataRetriever.UserAccountsUnit,
mrcf.enableEpochsHandler,
mrcf.stateStatsHandler,
)
if err != nil {
return fmt.Errorf("%w while creating user accounts data trie storage getter", err)
Expand Down Expand Up @@ -235,6 +237,7 @@ func (mrcf *metaRequestersContainerFactory) generateTrieNodesRequesters() error
peerAccountsCheckpointStorer,
dataRetriever.PeerAccountsUnit,
mrcf.enableEpochsHandler,
mrcf.stateStatsHandler,
)
if err != nil {
return fmt.Errorf("%w while creating peer accounts data trie storage getter", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func (srcf *shardRequestersContainerFactory) generateTrieNodesRequesters() error
userAccountsCheckpointStorer,
dataRetriever.UserAccountsUnit,
srcf.enableEpochsHandler,
srcf.stateStatsHandler,
BeniaminDrasovean marked this conversation as resolved.
Show resolved Hide resolved
)
if err != nil {
return fmt.Errorf("%w while creating user accounts data trie storage getter", err)
Expand Down