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 }