github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/sequencer/addrqueue_test.go (about)

     1  package sequencer
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  )
     9  
    10  type notReadyTx struct {
    11  	nonce uint64
    12  	hash  common.Hash
    13  }
    14  
    15  type addrQueueAddTxTestCase struct {
    16  	name               string
    17  	hash               common.Hash
    18  	nonce              uint64
    19  	gasPrice           *big.Int
    20  	cost               *big.Int
    21  	expectedReadyTx    common.Hash
    22  	expectedNotReadyTx []notReadyTx
    23  }
    24  
    25  var addr addrQueue
    26  
    27  func newTestTxTracker(hash common.Hash, nonce uint64, gasPrice *big.Int, cost *big.Int) *TxTracker {
    28  	tx := TxTracker{Hash: hash, Nonce: nonce, GasPrice: gasPrice, Cost: cost}
    29  	tx.HashStr = tx.Hash.String()
    30  	return &tx
    31  }
    32  
    33  func processAddTxTestCases(t *testing.T, testCases []addrQueueAddTxTestCase) {
    34  	var emptyHash common.Hash = common.Hash{}
    35  	for _, tc := range testCases {
    36  		t.Run(tc.name, func(t *testing.T) {
    37  			tx := newTestTxTracker(tc.hash, tc.nonce, tc.gasPrice, tc.cost)
    38  			newReadyTx, _, _ := addr.addTx(tx)
    39  			if tc.expectedReadyTx.String() == emptyHash.String() {
    40  				if !(addr.readyTx == nil) {
    41  					t.Fatalf("Error readyTx. Expected=%s, Actual=%s", tc.expectedReadyTx, "")
    42  				}
    43  				if !(newReadyTx == nil) {
    44  					t.Fatalf("Error newReadyTx. Expected=nil, Actual=%s", newReadyTx.HashStr)
    45  				}
    46  			} else {
    47  				if !(addr.readyTx.Hash == tc.expectedReadyTx) {
    48  					t.Fatalf("Error readyTx. Expected=%s, Actual=%s", tc.expectedReadyTx, addr.readyTx.HashStr)
    49  				}
    50  			}
    51  
    52  			for _, nr := range tc.expectedNotReadyTx {
    53  				txTmp, found := addr.notReadyTxs[nr.nonce]
    54  				if !(found) {
    55  					t.Fatalf("Error notReadyTx nonce=%d don't exists", nr.nonce)
    56  				}
    57  				if !(txTmp.Hash == nr.hash) {
    58  					t.Fatalf("Error notReadyTx nonce=%d. Expected=%s, Actual=%s", nr.nonce, nr.hash.String(), txTmp.HashStr)
    59  				}
    60  			}
    61  		})
    62  	}
    63  }
    64  
    65  func TestAddrQueue(t *testing.T) {
    66  	addr = addrQueue{fromStr: "0x99999", currentNonce: 1, currentBalance: new(big.Int).SetInt64(10), notReadyTxs: make(map[uint64]*TxTracker)}
    67  
    68  	addTxTestCases := []addrQueueAddTxTestCase{
    69  		{
    70  			name: "Add not ready tx 0x02", hash: common.Hash{0x2}, nonce: 2, gasPrice: new(big.Int).SetInt64(2), cost: new(big.Int).SetInt64(5),
    71  			expectedReadyTx: common.Hash{},
    72  			expectedNotReadyTx: []notReadyTx{
    73  				{nonce: 2, hash: common.Hash{0x2}},
    74  			},
    75  		},
    76  		{
    77  			name: "Add ready tx 0x01", hash: common.Hash{0x1}, nonce: 1, gasPrice: new(big.Int).SetInt64(2), cost: new(big.Int).SetInt64(5),
    78  			expectedReadyTx: common.Hash{1},
    79  			expectedNotReadyTx: []notReadyTx{
    80  				{nonce: 2, hash: common.Hash{0x2}},
    81  			},
    82  		},
    83  		{
    84  			name: "Add not ready tx 0x04", hash: common.Hash{0x4}, nonce: 4, gasPrice: new(big.Int).SetInt64(2), cost: new(big.Int).SetInt64(5),
    85  			expectedReadyTx: common.Hash{1},
    86  			expectedNotReadyTx: []notReadyTx{
    87  				{nonce: 2, hash: common.Hash{0x2}},
    88  				{nonce: 4, hash: common.Hash{0x4}},
    89  			},
    90  		},
    91  		{
    92  			name: "Replace tx with nonce 4 for tx 0x44 with best GasPrice", hash: common.Hash{0x44}, nonce: 4, gasPrice: new(big.Int).SetInt64(3), cost: new(big.Int).SetInt64(5),
    93  			expectedReadyTx: common.Hash{1},
    94  			expectedNotReadyTx: []notReadyTx{
    95  				{nonce: 2, hash: common.Hash{0x2}},
    96  				{nonce: 4, hash: common.Hash{0x44}},
    97  			},
    98  		},
    99  	}
   100  
   101  	processAddTxTestCases(t, addTxTestCases)
   102  
   103  	t.Run("Delete readyTx 0x01", func(t *testing.T) {
   104  		tc := addTxTestCases[1]
   105  		tx := newTestTxTracker(tc.hash, tc.nonce, tc.gasPrice, tc.cost)
   106  		deltx := addr.deleteTx(tx.Hash)
   107  		if !(addr.readyTx == nil) {
   108  			t.Fatalf("Error readyTx not nil. Expected=%s, Actual=%s", "", addr.readyTx.HashStr)
   109  		}
   110  		if !(deltx.HashStr == tx.HashStr) {
   111  			t.Fatalf("Error returning deletedReadyTx. Expected=%s, Actual=%s", tx.HashStr, deltx.HashStr)
   112  		}
   113  	})
   114  
   115  	processAddTxTestCases(t, []addrQueueAddTxTestCase{
   116  		{
   117  			name: "Add tx with nonce = currentNonce but with cost > currentBalance", hash: common.Hash{0x11}, nonce: 1, gasPrice: new(big.Int).SetInt64(2), cost: new(big.Int).SetInt64(15),
   118  			expectedReadyTx: common.Hash{},
   119  			expectedNotReadyTx: []notReadyTx{
   120  				{nonce: 1, hash: common.Hash{0x11}},
   121  				{nonce: 2, hash: common.Hash{0x2}},
   122  				{nonce: 4, hash: common.Hash{0x44}},
   123  			},
   124  		},
   125  	})
   126  
   127  	t.Run("Update currentBalance = 15, set tx 0x11 as ready", func(t *testing.T) {
   128  		tmpHash := common.Hash{0x11}
   129  		addr.updateCurrentNonceBalance(&addr.currentNonce, new(big.Int).SetInt64(15))
   130  		if !(addr.readyTx != nil && addr.readyTx.Hash.String() == tmpHash.String()) {
   131  			t.Fatalf("Error readyTx. Expected=%s, Actual=%s", tmpHash, "")
   132  		}
   133  
   134  		tx, found := addr.notReadyTxs[1]
   135  
   136  		if found {
   137  			t.Fatalf("Error notReadyTx nonce=%d. Expected=%s, Actual=%s", addr.currentNonce, "", tx.Hash.String())
   138  		}
   139  	})
   140  
   141  	t.Run("Update currentNonce = 4, set tx 0x04 as ready", func(t *testing.T) {
   142  		tmpHash := common.Hash{0x44}
   143  		newNonce := uint64(4)
   144  		addr.updateCurrentNonceBalance(&newNonce, new(big.Int).SetInt64(15))
   145  		if !(addr.readyTx != nil && addr.readyTx.Hash.String() == tmpHash.String()) {
   146  			t.Fatalf("Error readyTx. Expected=%s, Actual=%s", tmpHash, addr.readyTx.Hash.String())
   147  		}
   148  
   149  		if len(addr.notReadyTxs) > 0 {
   150  			t.Fatalf("Error notReadyTx not empty. Expected=%d, Actual=%d", 0, len(addr.notReadyTxs))
   151  		}
   152  	})
   153  }