@@ -1597,3 +1597,201 @@ func TestAdjustTimeAfterFork(t *testing.T) {
1597
1597
t .Errorf ("failed to build block on fork" )
1598
1598
}
1599
1599
}
1600
+
1601
+ // TestLowGasTxNotBeingMined checks that the lower gas fee tx with same nonce does not get mined
1602
+ // Steps:
1603
+ // 1. Send a tx lower than the set market gas price
1604
+ // 2. Commit to chain, check nonce stays the same
1605
+ // 3. Send a tx meets the market gas price with same nonce.
1606
+ // 4. Commit to chain
1607
+ // 5. Check tx2 is not in pending state and nonce has increased
1608
+ func TestLowGasTxNotBeingMined (t * testing.T ) {
1609
+ testAddr := crypto .PubkeyToAddress (testKey .PublicKey )
1610
+ var gas uint64 = 21000
1611
+
1612
+ sim := simTestBackend (testAddr )
1613
+ defer sim .Close ()
1614
+
1615
+ var testCases = []struct {
1616
+ name string
1617
+ txType byte
1618
+ }{
1619
+ {
1620
+ name : "LegacyTx" ,
1621
+ txType : types .LegacyTxType ,
1622
+ },
1623
+ {
1624
+ name : "dynamicTx" ,
1625
+ txType : types .DynamicFeeTxType ,
1626
+ },
1627
+ }
1628
+ for i , test := range testCases {
1629
+ t .Run (test .name , func (t * testing.T ) {
1630
+ bgCtx := context .Background ()
1631
+ // Create tx and send
1632
+ head , _ := sim .HeaderByNumber (context .Background (), nil )
1633
+ tip , err := sim .SuggestGasTipCap (bgCtx )
1634
+ require .NoError (t , err )
1635
+ gasPrice := new (big.Int ).Add (head .BaseFee , tip )
1636
+ sim .SetMarketGasPrice (int64 (gasPrice .Uint64 ()))
1637
+
1638
+ lowFeeGas := new (big.Int ).Sub (gasPrice , tip )
1639
+ txValue := big .NewInt (1 )
1640
+
1641
+ var lowGasFeeTx * types.Transaction
1642
+
1643
+ if test .txType == types .LegacyTxType {
1644
+ lowGasFeeTx = types .NewTx (& types.LegacyTx {
1645
+ Nonce : uint64 (i ),
1646
+ To : & testAddr ,
1647
+ Value : txValue ,
1648
+ GasPrice : lowFeeGas ,
1649
+ Gas : gas ,
1650
+ })
1651
+ } else if test .txType == types .DynamicFeeTxType {
1652
+ lowGasFeeTx = types .NewTx (& types.DynamicFeeTx {
1653
+ Nonce : uint64 (i ),
1654
+ Gas : gas ,
1655
+ To : & testAddr ,
1656
+ Value : txValue ,
1657
+ GasTipCap : lowFeeGas ,
1658
+ GasFeeCap : lowFeeGas ,
1659
+ })
1660
+ } else {
1661
+ t .Fatal ("unexpected txType received" )
1662
+ }
1663
+
1664
+ signedTx , err := types .SignTx (lowGasFeeTx , types .LatestSigner (sim .config ), testKey )
1665
+ require .NoError (t , err )
1666
+
1667
+ // send tx to simulated backend
1668
+ err = sim .SendTransaction (bgCtx , signedTx )
1669
+ require .NoError (t , err )
1670
+ sim .Commit ()
1671
+
1672
+ // expect nonce be the same because low gas fee tx will not be mined
1673
+ nonce , err := sim .PendingNonceAt (bgCtx , testAddr )
1674
+ require .NoError (t , err )
1675
+ assert .Equal (t , uint64 (i ), nonce )
1676
+
1677
+ // send tx with higher gas fee
1678
+ sufficientGasFeeTx := types .NewTx (& types.LegacyTx {
1679
+ Nonce : uint64 (i ),
1680
+ To : & testAddr ,
1681
+ Value : txValue ,
1682
+ GasPrice : gasPrice ,
1683
+ Gas : gas ,
1684
+ })
1685
+
1686
+ signedSufficientTx , err := types .SignTx (sufficientGasFeeTx , types.HomesteadSigner {}, testKey )
1687
+ require .NoError (t , err )
1688
+
1689
+ err = sim .SendTransaction (bgCtx , signedSufficientTx )
1690
+ require .NoError (t , err )
1691
+ sim .Commit ()
1692
+
1693
+ // the higher gas transaction should have been mined
1694
+ _ , isPending , err := sim .TransactionByHash (bgCtx , signedSufficientTx .Hash ())
1695
+ require .NoError (t , err )
1696
+ assert .False (t , isPending )
1697
+
1698
+ // expect nonce has increased
1699
+ nonce , err = sim .PendingNonceAt (bgCtx , testAddr )
1700
+ require .NoError (t , err )
1701
+ assert .Equal (t , uint64 (i )+ 1 , nonce )
1702
+ })
1703
+ }
1704
+ }
1705
+
1706
+ // TestLowGasTxGetMinedOnceGasFeeDropped checks that lower gas fee txes still stay in mem pool
1707
+ // and get mined once gas fee requirement has been met
1708
+ // Steps:
1709
+ // 1. Send a tx lower than the set market gas price
1710
+ // 2. Commit to chain, tx does not get mined
1711
+ // 3. Gas fee drops, commit again
1712
+ // 4. Check tx get mined
1713
+ func TestLowGasTxGetMinedOnceGasFeeDropped (t * testing.T ) {
1714
+ var testCases = []struct {
1715
+ name string
1716
+ txType byte
1717
+ }{
1718
+ {
1719
+ name : "LegacyTx" ,
1720
+ txType : types .LegacyTxType ,
1721
+ },
1722
+ {
1723
+ name : "dynamicTx" ,
1724
+ txType : types .DynamicFeeTxType ,
1725
+ },
1726
+ }
1727
+ testAddr := crypto .PubkeyToAddress (testKey .PublicKey )
1728
+ var gas uint64 = 21000
1729
+
1730
+ sim := simTestBackend (testAddr )
1731
+ defer sim .Close ()
1732
+
1733
+ for i , test := range testCases {
1734
+ t .Run (test .name , func (t * testing.T ) {
1735
+ bgCtx := context .Background ()
1736
+ // Create tx and send
1737
+ head , _ := sim .HeaderByNumber (context .Background (), nil )
1738
+ tip , err := sim .SuggestGasTipCap (bgCtx )
1739
+ require .NoError (t , err )
1740
+ normalGasPrice := new (big.Int ).Add (head .BaseFee , tip )
1741
+ highGasPrice := new (big.Int ).Add (head .BaseFee , big .NewInt (5 ))
1742
+
1743
+ sim .SetMarketGasPrice (int64 (highGasPrice .Uint64 ()))
1744
+
1745
+ var normalGasFeeTx * types.Transaction
1746
+ txValue := big .NewInt (1 )
1747
+
1748
+ if test .txType == types .LegacyTxType {
1749
+ normalGasFeeTx = types .NewTx (& types.LegacyTx {
1750
+ Nonce : uint64 (i ),
1751
+ To : & testAddr ,
1752
+ Value : txValue ,
1753
+ GasPrice : normalGasPrice ,
1754
+ Gas : gas ,
1755
+ })
1756
+ } else if test .txType == types .DynamicFeeTxType {
1757
+ normalGasFeeTx = types .NewTx (& types.DynamicFeeTx {
1758
+ Nonce : uint64 (i ),
1759
+ Gas : gas ,
1760
+ To : & testAddr ,
1761
+ Value : txValue ,
1762
+ GasTipCap : normalGasPrice ,
1763
+ GasFeeCap : normalGasPrice ,
1764
+ })
1765
+ } else {
1766
+ t .Fatal ("unexpected txType received" )
1767
+ }
1768
+
1769
+ signedTx , err := types .SignTx (normalGasFeeTx , types .LatestSigner (sim .config ), testKey )
1770
+ require .NoError (t , err )
1771
+
1772
+ // send tx to simulated backend
1773
+ err = sim .SendTransaction (bgCtx , signedTx )
1774
+ require .NoError (t , err )
1775
+ sim .Commit ()
1776
+
1777
+ // check that the nonce stays the same because nothing has been mined
1778
+ pendingNonce , err := sim .PendingNonceAt (bgCtx , testAddr )
1779
+ require .NoError (t , err )
1780
+ assert .Equal (t , uint64 (i ), pendingNonce )
1781
+
1782
+ // gas fee has dropped
1783
+ sim .SetMarketGasPrice (int64 (normalGasPrice .Uint64 ()))
1784
+ sim .Commit ()
1785
+
1786
+ // nonce has increased
1787
+ pendingNonce , err = sim .PendingNonceAt (bgCtx , testAddr )
1788
+ require .NoError (t , err )
1789
+ assert .Equal (t , uint64 (i )+ 1 , pendingNonce )
1790
+
1791
+ // the transaction should have been mined
1792
+ _ , isPending , err := sim .TransactionByHash (bgCtx , signedTx .Hash ())
1793
+ require .NoError (t , err )
1794
+ assert .False (t , isPending )
1795
+ })
1796
+ }
1797
+ }
0 commit comments