github.com/klaytn/klaytn@v1.12.1/blockchain/spam_throttler_test.go (about)

     1  package blockchain
     2  
     3  import (
     4  	"math/big"
     5  	"sync"
     6  	"testing"
     7  
     8  	"github.com/klaytn/klaytn/blockchain/types"
     9  	"github.com/klaytn/klaytn/common"
    10  	"github.com/klaytn/klaytn/params"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func newTestThrottler(config *ThrottlerConfig) *throttler {
    15  	return &throttler{
    16  		config:     config,
    17  		candidates: make(map[common.Address]int),
    18  		throttled:  make(map[common.Address]int),
    19  		allowed:    make(map[common.Address]bool),
    20  		mu:         new(sync.RWMutex),
    21  		threshold:  config.InitialThreshold,
    22  		throttleCh: make(chan *types.Transaction, config.ThrottleTPS*5),
    23  		quitCh:     make(chan struct{}),
    24  	}
    25  }
    26  
    27  func TestThrottler_updateThrottlerState(t *testing.T) {
    28  	testConfig := DefaultSpamThrottlerConfig
    29  	testCases := []struct {
    30  		tcName          string
    31  		txFailNum       int
    32  		candidateNum    int
    33  		candidateWeight int
    34  		throttledNum    int
    35  		throttledWeight int
    36  	}{
    37  		{
    38  			tcName:          "one address generates enough fail txs to be throttled",
    39  			txFailNum:       testConfig.InitialThreshold/testConfig.IncreaseWeight + 1,
    40  			candidateNum:    0,
    41  			candidateWeight: 0,
    42  			throttledNum:    1,
    43  			throttledWeight: testConfig.ThrottleSeconds,
    44  		},
    45  		{
    46  			tcName:       "one address generates not enough fail txs to be throttled",
    47  			txFailNum:    testConfig.InitialThreshold / testConfig.IncreaseWeight,
    48  			candidateNum: 1,
    49  			// th.config.IncreaseWeight * th.config.InitialThreshold / th.config.IncreaseWeight - th.config.DecreaseWeight
    50  			candidateWeight: testConfig.InitialThreshold - testConfig.DecreaseWeight,
    51  			throttledNum:    0,
    52  			throttledWeight: 0,
    53  		},
    54  	}
    55  
    56  	txNum := 1000
    57  	amount := big.NewInt(0)
    58  	gasLimit := uint64(10000)
    59  	gasPrice := big.NewInt(25 * params.Ston)
    60  	toFail := common.BytesToAddress(common.MakeRandomBytes(20))
    61  	toSuccess := common.BytesToAddress(common.MakeRandomBytes(20))
    62  
    63  	for _, tc := range testCases {
    64  		var txs types.Transactions
    65  		var receipts types.Receipts
    66  
    67  		// Reset throttler
    68  		th := newTestThrottler(testConfig)
    69  
    70  		// Generates fail txs
    71  		for i := 0; i < tc.txFailNum; i++ {
    72  			tx := types.NewTransaction(0, toFail, amount, gasLimit, gasPrice, nil)
    73  			receipt := &types.Receipt{
    74  				Status: types.ReceiptStatusFailed,
    75  			}
    76  			txs = append(txs, tx)
    77  			receipts = append(receipts, receipt)
    78  		}
    79  
    80  		// Generate success txs
    81  		for i := 0; i < txNum-tc.txFailNum; i++ {
    82  			tx := types.NewTransaction(0, toSuccess, amount, gasLimit, gasPrice, nil)
    83  			receipt := &types.Receipt{
    84  				Status: types.ReceiptStatusSuccessful,
    85  			}
    86  			txs = append(txs, tx)
    87  			receipts = append(receipts, receipt)
    88  		}
    89  
    90  		th.updateThrottlerState(txs, receipts)
    91  
    92  		assert.Equal(t, tc.candidateNum, len(th.candidates))
    93  		assert.Equal(t, tc.candidateWeight, th.candidates[toFail])
    94  		assert.Equal(t, tc.throttledNum, len(th.throttled))
    95  		assert.Equal(t, tc.throttledWeight, th.throttled[toFail])
    96  	}
    97  }