github.com/vipernet-xyz/tm@v0.34.24/p2p/trust/store_test.go (about)

     1  // Copyright 2017 Tendermint. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package trust
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	dbm "github.com/tendermint/tm-db"
    14  
    15  	"github.com/vipernet-xyz/tm/libs/log"
    16  )
    17  
    18  func TestTrustMetricStoreSaveLoad(t *testing.T) {
    19  	dir, err := os.MkdirTemp("", "trust_test")
    20  	require.NoError(t, err)
    21  	defer os.Remove(dir)
    22  
    23  	historyDB, err := dbm.NewDB("trusthistory", "goleveldb", dir)
    24  	require.NoError(t, err)
    25  
    26  	// 0 peers saved
    27  	store := NewTrustMetricStore(historyDB, DefaultConfig())
    28  	store.SetLogger(log.TestingLogger())
    29  	store.saveToDB()
    30  	// Load the data from the file
    31  	store = NewTrustMetricStore(historyDB, DefaultConfig())
    32  	store.SetLogger(log.TestingLogger())
    33  	err = store.Start()
    34  	require.NoError(t, err)
    35  	// Make sure we still have 0 entries
    36  	assert.Zero(t, store.Size())
    37  
    38  	// 100 TestTickers
    39  	var tt []*TestTicker
    40  	for i := 0; i < 100; i++ {
    41  		// The TestTicker will provide manual control over
    42  		// the passing of time within the metric
    43  		tt = append(tt, NewTestTicker())
    44  	}
    45  	// 100 peers
    46  	for i := 0; i < 100; i++ {
    47  		key := fmt.Sprintf("peer_%d", i)
    48  		tm := NewMetric()
    49  
    50  		tm.SetTicker(tt[i])
    51  		err = tm.Start()
    52  		require.NoError(t, err)
    53  		store.AddPeerTrustMetric(key, tm)
    54  
    55  		tm.BadEvents(10)
    56  		tm.GoodEvents(1)
    57  	}
    58  	// Check that we have 100 entries and save
    59  	assert.Equal(t, 100, store.Size())
    60  	// Give the 100 metrics time to process the history data
    61  	for i := 0; i < 100; i++ {
    62  		tt[i].NextTick()
    63  		tt[i].NextTick()
    64  	}
    65  	// Stop all the trust metrics and save
    66  	err = store.Stop()
    67  	require.NoError(t, err)
    68  
    69  	// Load the data from the DB
    70  	store = NewTrustMetricStore(historyDB, DefaultConfig())
    71  	store.SetLogger(log.TestingLogger())
    72  	err = store.Start()
    73  	require.NoError(t, err)
    74  
    75  	// Check that we still have 100 peers with imperfect trust values
    76  	assert.Equal(t, 100, store.Size())
    77  	for _, tm := range store.peerMetrics {
    78  		assert.NotEqual(t, 1.0, tm.TrustValue())
    79  	}
    80  
    81  	err = store.Stop()
    82  	require.NoError(t, err)
    83  }
    84  
    85  func TestTrustMetricStoreConfig(t *testing.T) {
    86  	historyDB, err := dbm.NewDB("", "memdb", "")
    87  	require.NoError(t, err)
    88  
    89  	config := MetricConfig{
    90  		ProportionalWeight: 0.5,
    91  		IntegralWeight:     0.5,
    92  	}
    93  
    94  	// Create a store with custom config
    95  	store := NewTrustMetricStore(historyDB, config)
    96  	store.SetLogger(log.TestingLogger())
    97  	err = store.Start()
    98  	require.NoError(t, err)
    99  
   100  	// Have the store make us a metric with the config
   101  	tm := store.GetPeerTrustMetric("TestKey")
   102  
   103  	// Check that the options made it to the metric
   104  	assert.Equal(t, 0.5, tm.proportionalWeight)
   105  	assert.Equal(t, 0.5, tm.integralWeight)
   106  	err = store.Stop()
   107  	require.NoError(t, err)
   108  }
   109  
   110  func TestTrustMetricStoreLookup(t *testing.T) {
   111  	historyDB, err := dbm.NewDB("", "memdb", "")
   112  	require.NoError(t, err)
   113  
   114  	store := NewTrustMetricStore(historyDB, DefaultConfig())
   115  	store.SetLogger(log.TestingLogger())
   116  	err = store.Start()
   117  	require.NoError(t, err)
   118  
   119  	// Create 100 peers in the trust metric store
   120  	for i := 0; i < 100; i++ {
   121  		key := fmt.Sprintf("peer_%d", i)
   122  		store.GetPeerTrustMetric(key)
   123  
   124  		// Check that the trust metric was successfully entered
   125  		ktm := store.peerMetrics[key]
   126  		assert.NotNil(t, ktm, "Expected to find TrustMetric %s but wasn't there.", key)
   127  	}
   128  
   129  	err = store.Stop()
   130  	require.NoError(t, err)
   131  }
   132  
   133  func TestTrustMetricStorePeerScore(t *testing.T) {
   134  	historyDB, err := dbm.NewDB("", "memdb", "")
   135  	require.NoError(t, err)
   136  
   137  	store := NewTrustMetricStore(historyDB, DefaultConfig())
   138  	store.SetLogger(log.TestingLogger())
   139  	err = store.Start()
   140  	require.NoError(t, err)
   141  
   142  	key := "TestKey"
   143  	tm := store.GetPeerTrustMetric(key)
   144  
   145  	// This peer is innocent so far
   146  	first := tm.TrustScore()
   147  	assert.Equal(t, 100, first)
   148  
   149  	// Add some undesirable events and disconnect
   150  	tm.BadEvents(1)
   151  	first = tm.TrustScore()
   152  	assert.NotEqual(t, 100, first)
   153  	tm.BadEvents(10)
   154  	second := tm.TrustScore()
   155  
   156  	if second > first {
   157  		t.Errorf("a greater number of bad events should lower the trust score")
   158  	}
   159  	store.PeerDisconnected(key)
   160  
   161  	// We will remember our experiences with this peer
   162  	tm = store.GetPeerTrustMetric(key)
   163  	assert.NotEqual(t, 100, tm.TrustScore())
   164  	err = store.Stop()
   165  	require.NoError(t, err)
   166  }