github.com/MetalBlockchain/subnet-evm@v0.4.9/plugin/evm/gasprice_update_test.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package evm
     5  
     6  import (
     7  	"math/big"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/MetalBlockchain/subnet-evm/params"
    13  )
    14  
    15  type mockGasPriceSetter struct {
    16  	lock          sync.Mutex
    17  	price, minFee *big.Int
    18  }
    19  
    20  func (m *mockGasPriceSetter) SetGasPrice(price *big.Int) {
    21  	m.lock.Lock()
    22  	defer m.lock.Unlock()
    23  
    24  	m.price = price
    25  }
    26  
    27  func (m *mockGasPriceSetter) SetMinFee(minFee *big.Int) {
    28  	m.lock.Lock()
    29  	defer m.lock.Unlock()
    30  
    31  	m.minFee = minFee
    32  }
    33  
    34  func (m *mockGasPriceSetter) GetStatus() (*big.Int, *big.Int) {
    35  	m.lock.Lock()
    36  	defer m.lock.Unlock()
    37  
    38  	return m.price, m.minFee
    39  }
    40  
    41  func attemptAwait(t *testing.T, wg *sync.WaitGroup, delay time.Duration) {
    42  	ticker := make(chan struct{})
    43  
    44  	// Wait for [wg] and then close [ticket] to indicate that
    45  	// the wait group has finished.
    46  	go func() {
    47  		wg.Wait()
    48  		close(ticker)
    49  	}()
    50  
    51  	select {
    52  	case <-time.After(delay):
    53  		t.Fatal("Timed out waiting for wait group to complete")
    54  	case <-ticker:
    55  		// The wait group completed without issue
    56  	}
    57  }
    58  
    59  func TestUpdateGasPriceShutsDown(t *testing.T) {
    60  	shutdownChan := make(chan struct{})
    61  	wg := &sync.WaitGroup{}
    62  	config := *params.TestChainConfig
    63  	// Set SubnetEVMBlockTime one hour in the future so that it will
    64  	// create a goroutine waiting for an hour before updating the gas price
    65  	config.SubnetEVMTimestamp = big.NewInt(time.Now().Add(time.Hour).Unix())
    66  
    67  	gpu := &gasPriceUpdater{
    68  		setter:       &mockGasPriceSetter{price: big.NewInt(1)},
    69  		chainConfig:  &config,
    70  		shutdownChan: shutdownChan,
    71  		wg:           wg,
    72  	}
    73  
    74  	gpu.start()
    75  	// Close [shutdownChan] and ensure that the wait group finishes in a reasonable
    76  	// amount of time.
    77  	close(shutdownChan)
    78  	attemptAwait(t, wg, 5*time.Second)
    79  }
    80  
    81  func TestUpdateGasPriceInitializesPrice(t *testing.T) {
    82  	shutdownChan := make(chan struct{})
    83  	wg := &sync.WaitGroup{}
    84  	gpu := &gasPriceUpdater{
    85  		setter:       &mockGasPriceSetter{price: big.NewInt(1)},
    86  		chainConfig:  params.TestChainConfig,
    87  		shutdownChan: shutdownChan,
    88  		wg:           wg,
    89  	}
    90  
    91  	gpu.start()
    92  	// The wait group should finish immediately since no goroutine
    93  	// should be created when all prices should be set from the start
    94  	attemptAwait(t, wg, time.Millisecond)
    95  
    96  	if gpu.setter.(*mockGasPriceSetter).price.Cmp(big.NewInt(0)) != 0 {
    97  		t.Fatalf("Expected price to match minimum base fee for subnet-evm")
    98  	}
    99  
   100  	if minFee := gpu.setter.(*mockGasPriceSetter).minFee; minFee == nil || minFee.Cmp(params.DefaultFeeConfig.MinBaseFee) != 0 {
   101  		t.Fatalf("Expected min fee to match minimum fee for subnet-evm, but found: %d", minFee)
   102  	}
   103  }
   104  
   105  func TestUpdateGasPriceUpdatesPrice(t *testing.T) {
   106  	shutdownChan := make(chan struct{})
   107  	wg := &sync.WaitGroup{}
   108  	config := *params.TestChainConfig
   109  	config.SubnetEVMTimestamp = big.NewInt(time.Now().Add(1 * time.Second).Unix())
   110  
   111  	gpu := &gasPriceUpdater{
   112  		setter:       &mockGasPriceSetter{price: big.NewInt(1)},
   113  		chainConfig:  &config,
   114  		shutdownChan: shutdownChan,
   115  		wg:           wg,
   116  	}
   117  
   118  	gpu.start()
   119  
   120  	// Confirm Subnet EVM settings are applied at the very end.
   121  	attemptAwait(t, wg, 5*time.Second)
   122  	price, minFee := gpu.setter.(*mockGasPriceSetter).GetStatus()
   123  	if price.Cmp(big.NewInt(0)) != 0 {
   124  		t.Fatalf("Expected price to match minimum base fee for subnet-evm")
   125  	}
   126  	if minFee == nil || minFee.Cmp(params.DefaultFeeConfig.MinBaseFee) != 0 {
   127  		t.Fatalf("Expected min fee to match minimum fee for subnet-evm, but found: %d", minFee)
   128  	}
   129  }