github.com/klaytn/klaytn@v1.12.1/consensus/misc/kip71_test.go (about)

     1  package misc
     2  
     3  import (
     4  	"math/big"
     5  	"math/rand"
     6  	"testing"
     7  
     8  	"github.com/klaytn/klaytn/blockchain/types"
     9  	"github.com/klaytn/klaytn/common"
    10  	"github.com/klaytn/klaytn/params"
    11  )
    12  
    13  func getTestConfig(forkedBlockNum *big.Int) *params.ChainConfig {
    14  	testConfig := params.CypressChainConfig
    15  	testConfig.UnitPrice = uint64(25000000000)
    16  	testConfig.MagmaCompatibleBlock = forkedBlockNum
    17  	testConfig.Governance = &params.GovernanceConfig{
    18  		KIP71: params.GetDefaultKIP71Config(),
    19  	}
    20  	return testConfig
    21  }
    22  
    23  func TestEvenBaseFee(t *testing.T) {
    24  	tests := []struct {
    25  		upperBoundBaseFee         uint64
    26  		lowerBoundBaseFee         uint64
    27  		gasTarget                 uint64
    28  		baseFeeDenominator        uint64
    29  		maxBlockGasUsedForBaseFee uint64
    30  		parentGasUsed             uint64
    31  		parentBaseFee             uint64
    32  	}{
    33  		// Current default setting
    34  		{750000000000, 25000000000, 30000000, 20, 60000000, 43212345, 13009212843},
    35  		{750000000000, 25000000000, 30000000, 20, 60000000, 34857284, 83009212843},
    36  		{750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843},
    37  		{750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843},
    38  		{750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843},
    39  		{750000000000, 25000000000, 30000000, 20, 60000000, 69856837, 34958439443},
    40  		{750000000000, 25000000000, 30000000, 20, 60000000, 18275847, 43459029443},
    41  		{750000000000, 25000000000, 30000000, 20, 60000000, 34857359, 43009212843},
    42  		{750000000000, 25000000000, 30000000, 20, 60000000, 28914728, 43009212843},
    43  		{750000000000, 25000000000, 30000000, 20, 60000000, 83597392, 43238573843},
    44  		{750000000000, 25000000000, 30000000, 20, 60000000, 28472874, 43009212843},
    45  		{750000000000, 25000000000, 30000000, 20, 60000000, 34895734, 43009212843},
    46  		{750000000000, 25000000000, 30000000, 20, 60000000, 17274858, 18432574843},
    47  		{750000000000, 25000000000, 30000000, 20, 60000000, 39093494, 43009212843},
    48  		{750000000000, 25000000000, 30000000, 20, 60000000, 18981884, 28574384343},
    49  		{750000000000, 25000000000, 30000000, 20, 60000000, 12873, 43009212843},
    50  		{750000000000, 25000000000, 30000000, 20, 60000000, 18273, 43009212843},
    51  		{750000000000, 25000000000, 30000000, 20, 60000000, 1, 43009212843},
    52  		{750000000000, 25000000000, 30000000, 20, 60000000, 18949, 43009212843},
    53  		{750000000000, 25000000000, 30000000, 20, 60000000, 19828, 43009212843},
    54  		// monkey test 1
    55  		{750000000001, 25123987327, 30000000, 20, 38573282, 83212345, 750000000000},
    56  		{750000000003, 25000000000, 30000000, 20, 83478211, 43212345, 48572839123},
    57  		{750000000005, 25000000000, 30000000, 20, 48471293, 43212345, 48572839123},
    58  		{750000000006, 25000000000, 30000000, 20, 43852728, 43212345, 48572839123},
    59  		{750000000007, 25000000000, 30000000, 20, 11282848, 43212345, 48572839123},
    60  		{750000000009, 25000000000, 30000000, 20, 38574848, 43212345, 48572839123},
    61  		{800000001233, 25000000000, 30000000, 20, 83839191, 43212345, 48572839123},
    62  		{751231231233, 25000000000, 30000000, 20, 88391928, 43212345, 48572839123},
    63  		{750321321321, 25000000000, 30000000, 20, 60000000, 43212345, 48572839123},
    64  		{750000000777, 25000000000, 30000000, 20, 60000000, 43212345, 48572839123},
    65  		// monkey test 2
    66  		{750000000000, 28347289478, 30000000, 20, 60000000, 43212345, 75489234128},
    67  		{750000000000, 28729584848, 30000000, 20, 60000000, 43212345, 75489234128},
    68  		{0, 0, 30000000, 20, 60000000, 0, 43009212843},
    69  		{750000000000, 29999999999, 30000000, 20, 60000000, 43212345, 75489234128},
    70  		{750000000000, 19999999999, 30000000, 20, 60000000, 43212345, 75489234128},
    71  		{750000000000, 0, 30000000, 20, 60000000, 43212345, 75489234128},
    72  		{750000000000, 1, 30000000, 1, 60000000, 0, 10},
    73  		{750000000000, 0, 30000000, 20, 60000000, 43212345, 75489234128},
    74  		{0, 0, 30000000, 20, 60000000, 43212345, 75489234128},
    75  		{0, 0, 30000000, 20, 60000000, 43212345, 75489234128},
    76  	}
    77  
    78  	testConfig := getTestConfig(big.NewInt(3))
    79  	for _, test := range tests {
    80  		testConfig.Governance.KIP71.LowerBoundBaseFee = test.lowerBoundBaseFee
    81  		testConfig.Governance.KIP71.UpperBoundBaseFee = test.upperBoundBaseFee
    82  		testConfig.Governance.KIP71.GasTarget = test.gasTarget
    83  		testConfig.Governance.KIP71.MaxBlockGasUsedForBaseFee = test.maxBlockGasUsedForBaseFee
    84  		testConfig.Governance.KIP71.BaseFeeDenominator = test.baseFeeDenominator
    85  
    86  		parent := &types.Header{
    87  			Number:  common.Big3,
    88  			GasUsed: test.parentGasUsed,
    89  			BaseFee: new(big.Int).SetUint64(test.parentBaseFee),
    90  		}
    91  		even := NextMagmaBlockBaseFee(parent, testConfig.Governance.KIP71)
    92  		// even check
    93  		if even.Bit(0) != 0 {
    94  			t.Errorf("NextBlockBaseFee:%d is not a even number", even)
    95  		}
    96  		// lower bound check
    97  		if even.Cmp(new(big.Int).SetUint64(test.lowerBoundBaseFee)) < 0 {
    98  			t.Errorf("NextBlockBaseFee:%d is lower than lowerBoudnBaseFee:%d", even, test.lowerBoundBaseFee)
    99  		}
   100  		// upper bound check
   101  		if even.Cmp(new(big.Int).SetUint64(test.upperBoundBaseFee)) > 0 {
   102  			t.Errorf("NextBlockBaseFee:%d exceeded upperBoudnBaseFee:%d", even, test.upperBoundBaseFee)
   103  		}
   104  	}
   105  }
   106  
   107  func TestNextBlockBaseFee(t *testing.T) {
   108  	tests := []struct {
   109  		parentBaseFee int64
   110  		parentGasUsed uint64
   111  		nextBaseFee   int64
   112  	}{
   113  		{750000000000, 30000000, 750000000000}, // usage == target
   114  		{30000000000, 20000000, 29500000000},   // usage below target
   115  		{300000000000, 40000000, 305000000000}, // usage above target
   116  	}
   117  	for i, test := range tests {
   118  		parent := &types.Header{
   119  			Number:  common.Big3,
   120  			GasUsed: test.parentGasUsed,
   121  			BaseFee: big.NewInt(test.parentBaseFee),
   122  		}
   123  		if have, want := NextMagmaBlockBaseFee(
   124  			parent,
   125  			getTestConfig(big.NewInt(3)).Governance.KIP71),
   126  			big.NewInt(test.nextBaseFee); have.Cmp(want) != 0 {
   127  			t.Errorf("test %d: have %d  want %d, ", i, have, want)
   128  		}
   129  	}
   130  }
   131  
   132  func TestNextBlockBaseFeeWhenGovernanceUpdated(t *testing.T) {
   133  	tests := []struct {
   134  		upperBoundBaseFee uint64 // updated upper bound
   135  		lowerBoundBaseFee uint64 // updated lower bound
   136  		parentGasUsed     uint64
   137  		parentBaseFee     int64
   138  		nextBaseFee       int64
   139  	}{
   140  		{750000000000, 25000000000, 30000000, 750000000000, 750000000000},
   141  		{700000000000, 25000000000, 30000000, 750000000000, 700000000000},
   142  		{800000000000, 25000000000, 30000000, 750000000000, 750000000000},
   143  		{750000000000, 25000000000, 30000000, 25000000000, 25000000000},
   144  		{750000000000, 30000000000, 30000000, 25000000000, 30000000000},
   145  		{750000000000, 20000000000, 30000000, 25000000000, 25000000000},
   146  		{750000000000, 25000000000, 40000000 /* > gasTarget(30000000) */, 750000000000, 750000000000},
   147  		{750000000000, 25000000000, 20000000 /* < gasTarget(30000000) */, 25000000000, 25000000000},
   148  	}
   149  	for i, test := range tests {
   150  		config := getTestConfig(common.Big2)
   151  		config.Governance.KIP71.UpperBoundBaseFee = test.upperBoundBaseFee
   152  		config.Governance.KIP71.LowerBoundBaseFee = test.lowerBoundBaseFee
   153  		parent := &types.Header{
   154  			Number:  common.Big3,
   155  			GasUsed: test.parentGasUsed,
   156  			BaseFee: big.NewInt(test.parentBaseFee),
   157  		}
   158  		if have, want := NextMagmaBlockBaseFee(parent, config.Governance.KIP71), big.NewInt(test.nextBaseFee); have.Cmp(want) != 0 {
   159  			t.Errorf("test %d: have %d  want %d, ", i, have, want)
   160  		}
   161  	}
   162  }
   163  
   164  type BaseFeeTestCase struct {
   165  	genesisParentBaseFee *big.Int
   166  	hardforkedNum        *big.Int
   167  	GasUsed              uint64
   168  	compMethod           func(*big.Int, *big.Int) bool
   169  	expectedBaseFee      *big.Int
   170  	expectedNum          int
   171  }
   172  
   173  func TestBlocksToReachExpectedBaseFee(t *testing.T) {
   174  	testCases := []BaseFeeTestCase{
   175  		{
   176  			big.NewInt(25000000000),
   177  			common.Big3,
   178  			84000000,
   179  			func(a *big.Int, b *big.Int) bool { return a.Cmp(b) > 0 },
   180  			big.NewInt(25000000000 * 2),
   181  			15,
   182  		},
   183  		{
   184  			big.NewInt(60000000000),
   185  			common.Big3,
   186  			29000000,
   187  			func(a *big.Int, b *big.Int) bool { return a.Cmp(b) < 0 },
   188  			big.NewInt(60000000000 / 2),
   189  			416,
   190  		},
   191  		{
   192  			big.NewInt(25000000000),
   193  			common.Big3,
   194  			84000000,
   195  			func(a *big.Int, b *big.Int) bool { return a.Cmp(b) == 0 },
   196  			big.NewInt(750000000000),
   197  			70,
   198  		},
   199  		{
   200  			big.NewInt(750000000000),
   201  			common.Big3,
   202  			29000000,
   203  			func(a *big.Int, b *big.Int) bool { return a.Cmp(b) == 0 },
   204  			big.NewInt(25000000000),
   205  			2040,
   206  		},
   207  	}
   208  
   209  	for _, testCase := range testCases {
   210  		blocksToReachExpectedBaseFee(t, testCase)
   211  	}
   212  }
   213  
   214  func blocksToReachExpectedBaseFee(t *testing.T, testCase BaseFeeTestCase) {
   215  	testConfig := getTestConfig(big.NewInt(3))
   216  	blockNum := 0
   217  	parentBaseFee := testCase.genesisParentBaseFee
   218  	for {
   219  		blockNum++
   220  		parent := &types.Header{
   221  			Number:  testCase.hardforkedNum,
   222  			GasUsed: testCase.GasUsed,
   223  			BaseFee: parentBaseFee,
   224  		}
   225  		parentBaseFee = NextMagmaBlockBaseFee(parent, testConfig.Governance.KIP71)
   226  
   227  		if testCase.compMethod(parentBaseFee, testCase.expectedBaseFee) {
   228  			break
   229  		}
   230  	}
   231  	if blockNum != int(testCase.expectedNum) {
   232  		t.Errorf("block number %d expected block number %d, have %d didn't reach to %d", blockNum, testCase.expectedNum, parentBaseFee, testCase.expectedBaseFee)
   233  	}
   234  }
   235  
   236  func TestInactieDynamicPolicyBeforeForkedBlock(t *testing.T) {
   237  	parentBaseFee := big.NewInt(25000000000)
   238  	parent := &types.Header{
   239  		Number:  common.Big3,
   240  		GasUsed: 84000000,
   241  	}
   242  	nextBaseFee := NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(5)).Governance.KIP71)
   243  	if parentBaseFee.Cmp(nextBaseFee) < 0 {
   244  		t.Errorf("before fork, dynamic base fee policy should be inactive, current base fee: %d  next base fee: %d", parentBaseFee, nextBaseFee)
   245  	}
   246  }
   247  
   248  func TestActieDynamicPolicyAfterForkedBlock(t *testing.T) {
   249  	parentBaseFee := big.NewInt(25000000000)
   250  	parent := &types.Header{
   251  		Number:  common.Big3,
   252  		GasUsed: 84000000,
   253  		BaseFee: parentBaseFee,
   254  	}
   255  	nextBaseFee := NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71)
   256  	if parentBaseFee.Cmp(nextBaseFee) > 0 {
   257  		t.Errorf("after fork, dynamic base fee policy should be active, current base fee: %d  next base fee: %d", parentBaseFee, nextBaseFee)
   258  	}
   259  }
   260  
   261  func BenchmarkNextBlockBaseFeeRandom(b *testing.B) {
   262  	parentBaseFee := big.NewInt(500000000000)
   263  	parent := &types.Header{
   264  		Number:  common.Big3,
   265  		GasUsed: 10000000,
   266  		BaseFee: parentBaseFee,
   267  	}
   268  	for i := 0; i < b.N; i++ {
   269  		if rand.Int()%2 == 0 {
   270  			parent.GasUsed = 10000000
   271  		} else {
   272  			parent.GasUsed = 40000000
   273  		}
   274  		_ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71)
   275  	}
   276  }
   277  
   278  func BenchmarkNextBlockBaseFeeUpperBound(b *testing.B) {
   279  	parentBaseFee := big.NewInt(750000000000)
   280  	parent := &types.Header{
   281  		Number:  common.Big3,
   282  		GasUsed: 40000000,
   283  		BaseFee: parentBaseFee,
   284  	}
   285  	for i := 0; i < b.N; i++ {
   286  		_ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71)
   287  	}
   288  }
   289  
   290  func BenchmarkNextBlockBaseFeeLowerBound(b *testing.B) {
   291  	parentBaseFee := big.NewInt(25000000000)
   292  	parent := &types.Header{
   293  		Number:  common.Big3,
   294  		GasUsed: 10000000,
   295  		BaseFee: parentBaseFee,
   296  	}
   297  	for i := 0; i < b.N; i++ {
   298  		_ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71)
   299  	}
   300  }