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