@@ -77,9 +77,17 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
7777 return tx
7878}
7979
80+ func pricedDataTransaction (nonce uint64 , gaslimit uint64 , gasprice * big.Int , key * ecdsa.PrivateKey , bytes uint64 ) * types.Transaction {
81+ data := make ([]byte , bytes )
82+ rand .Read (data )
83+
84+ tx , _ := types .SignTx (types .NewTransaction (nonce , common.Address {}, big .NewInt (0 ), gaslimit , gasprice , data ), types.HomesteadSigner {}, key )
85+ return tx
86+ }
87+
8088func setupTxPool () (* TxPool , * ecdsa.PrivateKey ) {
8189 statedb , _ := state .New (common.Hash {}, state .NewDatabase (rawdb .NewMemoryDatabase ()))
82- blockchain := & testBlockChain {statedb , 1000000 , new (event.Feed )}
90+ blockchain := & testBlockChain {statedb , 10000000 , new (event.Feed )}
8391
8492 key , _ := crypto .GenerateKey ()
8593 pool := NewTxPool (testTxPoolConfig , params .TestChainConfig , blockchain )
@@ -465,7 +473,7 @@ func TestTransactionDropping(t *testing.T) {
465473 pool , key := setupTxPool ()
466474 defer pool .Stop ()
467475
468- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
476+ account := crypto . PubkeyToAddress ( key . PublicKey )
469477 pool .currentState .AddBalance (account , big .NewInt (1000 ))
470478
471479 // Add some pending and some queued transactions
@@ -674,7 +682,7 @@ func TestTransactionGapFilling(t *testing.T) {
674682 pool , key := setupTxPool ()
675683 defer pool .Stop ()
676684
677- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
685+ account := crypto . PubkeyToAddress ( key . PublicKey )
678686 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
679687
680688 // Keep track of transaction events to ensure all executables get announced
@@ -728,7 +736,7 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
728736 pool , key := setupTxPool ()
729737 defer pool .Stop ()
730738
731- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
739+ account := crypto . PubkeyToAddress ( key . PublicKey )
732740 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
733741
734742 // Keep queuing up transactions and make sure all above a limit are dropped
@@ -923,7 +931,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
923931 pool , key := setupTxPool ()
924932 defer pool .Stop ()
925933
926- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
934+ account := crypto . PubkeyToAddress ( key . PublicKey )
927935 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
928936
929937 // Keep track of transaction events to ensure all executables get announced
@@ -1002,6 +1010,62 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
10021010 }
10031011}
10041012
1013+ // Test the limit on transaction size is enforced correctly.
1014+ // This test verifies every transaction having allowed size
1015+ // is added to the pool, and longer transactions are rejected.
1016+ func TestTransactionAllowedTxSize (t * testing.T ) {
1017+ t .Parallel ()
1018+
1019+ // Create a test account and fund it
1020+ pool , key := setupTxPool ()
1021+ defer pool .Stop ()
1022+
1023+ account := crypto .PubkeyToAddress (key .PublicKey )
1024+ pool .currentState .AddBalance (account , big .NewInt (1000000000 ))
1025+
1026+ // Compute maximal data size for transactions (lower bound).
1027+ //
1028+ // It is assumed the fields in the transaction (except of the data) are:
1029+ // - nonce <= 32 bytes
1030+ // - gasPrice <= 32 bytes
1031+ // - gasLimit <= 32 bytes
1032+ // - recipient == 20 bytes
1033+ // - value <= 32 bytes
1034+ // - signature == 65 bytes
1035+ // All those fields are summed up to at most 213 bytes.
1036+ baseSize := uint64 (213 )
1037+ dataSize := txMaxSize - baseSize
1038+
1039+ // Try adding a transaction with maximal allowed size
1040+ tx := pricedDataTransaction (0 , pool .currentMaxGas , big .NewInt (1 ), key , dataSize )
1041+ if err := pool .addRemoteSync (tx ); err != nil {
1042+ t .Fatalf ("failed to add transaction of size %d, close to maximal: %v" , int (tx .Size ()), err )
1043+ }
1044+ // Try adding a transaction with random allowed size
1045+ if err := pool .addRemoteSync (pricedDataTransaction (1 , pool .currentMaxGas , big .NewInt (1 ), key , uint64 (rand .Intn (int (dataSize ))))); err != nil {
1046+ t .Fatalf ("failed to add transaction of random allowed size: %v" , err )
1047+ }
1048+ // Try adding a transaction of minimal not allowed size
1049+ if err := pool .addRemoteSync (pricedDataTransaction (2 , pool .currentMaxGas , big .NewInt (1 ), key , txMaxSize )); err == nil {
1050+ t .Fatalf ("expected rejection on slightly oversize transaction" )
1051+ }
1052+ // Try adding a transaction of random not allowed size
1053+ if err := pool .addRemoteSync (pricedDataTransaction (2 , pool .currentMaxGas , big .NewInt (1 ), key , dataSize + 1 + uint64 (rand .Intn (int (10 * txMaxSize ))))); err == nil {
1054+ t .Fatalf ("expected rejection on oversize transaction" )
1055+ }
1056+ // Run some sanity checks on the pool internals
1057+ pending , queued := pool .Stats ()
1058+ if pending != 2 {
1059+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 2 )
1060+ }
1061+ if queued != 0 {
1062+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 0 )
1063+ }
1064+ if err := validateTxPoolInternals (pool ); err != nil {
1065+ t .Fatalf ("pool internal state corrupted: %v" , err )
1066+ }
1067+ }
1068+
10051069// Tests that if transactions start being capped, transactions are also removed from 'all'
10061070func TestTransactionCapClearsFromAll (t * testing.T ) {
10071071 t .Parallel ()
@@ -1752,6 +1816,24 @@ func TestTransactionStatusCheck(t *testing.T) {
17521816 }
17531817}
17541818
1819+ // Test the transaction slots consumption is computed correctly
1820+ func TestTransactionSlotCount (t * testing.T ) {
1821+ t .Parallel ()
1822+
1823+ key , _ := crypto .GenerateKey ()
1824+
1825+ // Check that an empty transaction consumes a single slot
1826+ smallTx := pricedDataTransaction (0 , 0 , big .NewInt (0 ), key , 0 )
1827+ if slots := numSlots (smallTx ); slots != 1 {
1828+ t .Fatalf ("small transactions slot count mismatch: have %d want %d" , slots , 1 )
1829+ }
1830+ // Check that a large transaction consumes the correct number of slots
1831+ bigTx := pricedDataTransaction (0 , 0 , big .NewInt (0 ), key , uint64 (10 * txSlotSize ))
1832+ if slots := numSlots (bigTx ); slots != 11 {
1833+ t .Fatalf ("big transactions slot count mismatch: have %d want %d" , slots , 11 )
1834+ }
1835+ }
1836+
17551837// Benchmarks the speed of validating the contents of the pending queue of the
17561838// transaction pool.
17571839func BenchmarkPendingDemotion100 (b * testing.B ) { benchmarkPendingDemotion (b , 100 ) }
@@ -1763,7 +1845,7 @@ func benchmarkPendingDemotion(b *testing.B, size int) {
17631845 pool , key := setupTxPool ()
17641846 defer pool .Stop ()
17651847
1766- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
1848+ account := crypto . PubkeyToAddress ( key . PublicKey )
17671849 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
17681850
17691851 for i := 0 ; i < size ; i ++ {
@@ -1788,7 +1870,7 @@ func benchmarkFuturePromotion(b *testing.B, size int) {
17881870 pool , key := setupTxPool ()
17891871 defer pool .Stop ()
17901872
1791- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
1873+ account := crypto . PubkeyToAddress ( key . PublicKey )
17921874 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
17931875
17941876 for i := 0 ; i < size ; i ++ {
@@ -1812,7 +1894,7 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) {
18121894 pool , key := setupTxPool ()
18131895 defer pool .Stop ()
18141896
1815- account , _ := deriveSender ( transaction ( 0 , 0 , key ) )
1897+ account := crypto . PubkeyToAddress ( key . PublicKey )
18161898 pool .currentState .AddBalance (account , big .NewInt (1000000 ))
18171899
18181900 batches := make ([]types.Transactions , b .N )
0 commit comments