| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | // Copyright 2020 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package ethtest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/internal/utesting" | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var faucetAddr = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") | 
					
						
							|  |  |  | var faucetKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func (s *Suite) sendSuccessfulTxs(t *utesting.T, isEth66 bool) error { | 
					
						
							|  |  |  | 	tests := []*types.Transaction{ | 
					
						
							|  |  |  | 		getNextTxFromChain(s), | 
					
						
							|  |  |  | 		unknownTx(s), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, tx := range tests { | 
					
						
							|  |  |  | 		if tx == nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("could not find tx to send") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		t.Logf("Testing tx propagation %d: sending tx %v %v %v\n", i, tx.Hash().String(), tx.GasPrice(), tx.Gas()) | 
					
						
							|  |  |  | 		// get previous tx if exists for reference in case of old tx propagation | 
					
						
							|  |  |  | 		var prevTx *types.Transaction | 
					
						
							|  |  |  | 		if i != 0 { | 
					
						
							|  |  |  | 			prevTx = tests[i-1] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// write tx to connection | 
					
						
							|  |  |  | 		if err := sendSuccessfulTx(s, tx, prevTx, isEth66); err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("send successful tx test failed: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func sendSuccessfulTx(s *Suite, tx *types.Transaction, prevTx *types.Transaction, isEth66 bool) error { | 
					
						
							|  |  |  | 	sendConn, recvConn, err := s.createSendAndRecvConns(isEth66) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer sendConn.Close() | 
					
						
							|  |  |  | 	defer recvConn.Close() | 
					
						
							|  |  |  | 	if err = sendConn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	// Send the transaction | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err = sendConn.Write(&Transactions{tx}); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// peer receiving connection to node | 
					
						
							|  |  |  | 	if err = recvConn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	// update last nonce seen | 
					
						
							|  |  |  | 	nonce = tx.Nonce() | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	// Wait for the transaction announcement | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	for { | 
					
						
							|  |  |  | 		switch msg := recvConn.readAndServe(s.chain, timeout).(type) { | 
					
						
							|  |  |  | 		case *Transactions: | 
					
						
							|  |  |  | 			recTxs := *msg | 
					
						
							|  |  |  | 			// if you receive an old tx propagation, read from connection again | 
					
						
							|  |  |  | 			if len(recTxs) == 1 && prevTx != nil { | 
					
						
							|  |  |  | 				if recTxs[0] == prevTx { | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			for _, gotTx := range recTxs { | 
					
						
							|  |  |  | 				if gotTx.Hash() == tx.Hash() { | 
					
						
							|  |  |  | 					// Ok | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			return fmt.Errorf("missing transaction: got %v missing %v", recTxs, tx.Hash()) | 
					
						
							|  |  |  | 		case *NewPooledTransactionHashes: | 
					
						
							|  |  |  | 			txHashes := *msg | 
					
						
							|  |  |  | 			// if you receive an old tx propagation, read from connection again | 
					
						
							|  |  |  | 			if len(txHashes) == 1 && prevTx != nil { | 
					
						
							|  |  |  | 				if txHashes[0] == prevTx.Hash() { | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for _, gotHash := range txHashes { | 
					
						
							|  |  |  | 				if gotHash == tx.Hash() { | 
					
						
							|  |  |  | 					// Ok | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return fmt.Errorf("missing transaction announcement: got %v missing %v", txHashes, tx.Hash()) | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			return fmt.Errorf("unexpected message in sendSuccessfulTx: %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func (s *Suite) sendMaliciousTxs(t *utesting.T, isEth66 bool) error { | 
					
						
							|  |  |  | 	badTxs := []*types.Transaction{ | 
					
						
							|  |  |  | 		getOldTxFromChain(s), | 
					
						
							|  |  |  | 		invalidNonceTx(s), | 
					
						
							|  |  |  | 		hugeAmount(s), | 
					
						
							|  |  |  | 		hugeGasPrice(s), | 
					
						
							|  |  |  | 		hugeData(s), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// setup receiving connection before sending malicious txs | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		recvConn *Conn | 
					
						
							|  |  |  | 		err      error | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if isEth66 { | 
					
						
							|  |  |  | 		recvConn, err = s.dial66() | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		recvConn, err = s.dial() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer recvConn.Close() | 
					
						
							|  |  |  | 	if err = recvConn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, tx := range badTxs { | 
					
						
							|  |  |  | 		t.Logf("Testing malicious tx propagation: %v\n", i) | 
					
						
							|  |  |  | 		if err = sendMaliciousTx(s, tx, isEth66); err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("malicious tx test failed:\ntx: %v\nerror: %v", tx, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check to make sure bad txs aren't propagated | 
					
						
							|  |  |  | 	return checkMaliciousTxPropagation(s, badTxs, recvConn) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func sendMaliciousTx(s *Suite, tx *types.Transaction, isEth66 bool) error { | 
					
						
							|  |  |  | 	// setup connection | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		conn *Conn | 
					
						
							|  |  |  | 		err  error | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if isEth66 { | 
					
						
							|  |  |  | 		conn, err = s.dial66() | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		conn, err = s.dial() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err = conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write malicious tx | 
					
						
							|  |  |  | 	if err = conn.Write(&Transactions{tx}); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | var nonce = uint64(99) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // sendMultipleSuccessfulTxs sends the given transactions to the node and | 
					
						
							|  |  |  | // expects the node to accept and propagate them. | 
					
						
							|  |  |  | func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, txs []*types.Transaction) error { | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	txMsg := Transactions(txs) | 
					
						
							|  |  |  | 	t.Logf("sending %d txs\n", len(txs)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	sendConn, recvConn, err := s.createSendAndRecvConns(true) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer sendConn.Close() | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	defer recvConn.Close() | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err = sendConn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err = recvConn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	// Send the transactions | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err = sendConn.Write(&txMsg); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("failed to write message to connection: %v", err) | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// update nonce | 
					
						
							|  |  |  | 	nonce = txs[len(txs)-1].Nonce() | 
					
						
							|  |  |  | 	// Wait for the transaction announcement(s) and make sure all sent txs are being propagated | 
					
						
							|  |  |  | 	recvHashes := make([]common.Hash, 0) | 
					
						
							|  |  |  | 	// all txs should be announced within 3 announcements | 
					
						
							|  |  |  | 	for i := 0; i < 3; i++ { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		switch msg := recvConn.readAndServe(s.chain, timeout).(type) { | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 		case *Transactions: | 
					
						
							|  |  |  | 			for _, tx := range *msg { | 
					
						
							|  |  |  | 				recvHashes = append(recvHashes, tx.Hash()) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case *NewPooledTransactionHashes: | 
					
						
							|  |  |  | 			recvHashes = append(recvHashes, *msg...) | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			if !strings.Contains(pretty.Sdump(msg), "i/o timeout") { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 				return fmt.Errorf("unexpected message while waiting to receive txs: %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// break once all 2000 txs have been received | 
					
						
							|  |  |  | 		if len(recvHashes) == 2000 { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(recvHashes) > 0 { | 
					
						
							|  |  |  | 			_, missingTxs := compareReceivedTxs(recvHashes, txs) | 
					
						
							|  |  |  | 			if len(missingTxs) > 0 { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				t.Logf("successfully received all %d txs", len(txs)) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 				return nil | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, missingTxs := compareReceivedTxs(recvHashes, txs) | 
					
						
							|  |  |  | 	if len(missingTxs) > 0 { | 
					
						
							|  |  |  | 		for _, missing := range missingTxs { | 
					
						
							|  |  |  | 			t.Logf("missing tx: %v", missing.Hash()) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		return fmt.Errorf("missing %d txs", len(missingTxs)) | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // checkMaliciousTxPropagation checks whether the given malicious transactions were | 
					
						
							|  |  |  | // propagated by the node. | 
					
						
							|  |  |  | func checkMaliciousTxPropagation(s *Suite, txs []*types.Transaction, conn *Conn) error { | 
					
						
							|  |  |  | 	switch msg := conn.readAndServe(s.chain, time.Second*8).(type) { | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	case *Transactions: | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		// check to see if any of the failing txs were in the announcement | 
					
						
							|  |  |  | 		recvTxs := make([]common.Hash, len(*msg)) | 
					
						
							|  |  |  | 		for i, recvTx := range *msg { | 
					
						
							|  |  |  | 			recvTxs[i] = recvTx.Hash() | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 		badTxs, _ := compareReceivedTxs(recvTxs, txs) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		if len(badTxs) > 0 { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			return fmt.Errorf("received %d bad txs: \n%v", len(badTxs), badTxs) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	case *NewPooledTransactionHashes: | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 		badTxs, _ := compareReceivedTxs(*msg, txs) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		if len(badTxs) > 0 { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			return fmt.Errorf("received %d bad txs: \n%v", len(badTxs), badTxs) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	case *Error: | 
					
						
							|  |  |  | 		// Transaction should not be announced -> wait for timeout | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		return fmt.Errorf("unexpected message in sendFailingTx: %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | // compareReceivedTxs compares the received set of txs against the given set of txs, | 
					
						
							|  |  |  | // returning both the set received txs that were present within the given txs, and | 
					
						
							|  |  |  | // the set of txs that were missing from the set of received txs | 
					
						
							|  |  |  | func compareReceivedTxs(recvTxs []common.Hash, txs []*types.Transaction) (present []*types.Transaction, missing []*types.Transaction) { | 
					
						
							|  |  |  | 	// create a map of the hashes received from node | 
					
						
							|  |  |  | 	recvHashes := make(map[common.Hash]common.Hash) | 
					
						
							|  |  |  | 	for _, hash := range recvTxs { | 
					
						
							|  |  |  | 		recvHashes[hash] = hash | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// collect present txs and missing txs separately | 
					
						
							|  |  |  | 	present = make([]*types.Transaction, 0) | 
					
						
							|  |  |  | 	missing = make([]*types.Transaction, 0) | 
					
						
							|  |  |  | 	for _, tx := range txs { | 
					
						
							|  |  |  | 		if _, exists := recvHashes[tx.Hash()]; exists { | 
					
						
							|  |  |  | 			present = append(present, tx) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			missing = append(missing, tx) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	return present, missing | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func unknownTx(s *Suite) *types.Transaction { | 
					
						
							|  |  |  | 	tx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	if tx.To() != nil { | 
					
						
							|  |  |  | 		to = *tx.To() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	txNew := types.NewTransaction(tx.Nonce()+1, to, tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data()) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(s.chain.chainConfig, txNew) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func getNextTxFromChain(s *Suite) *types.Transaction { | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	// Get a new transaction | 
					
						
							|  |  |  | 	for _, blocks := range s.fullChain.blocks[s.chain.Len():] { | 
					
						
							|  |  |  | 		txs := blocks.Transactions() | 
					
						
							|  |  |  | 		if txs.Len() != 0 { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			return txs[0] | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func generateTxs(s *Suite, numTxs int) (map[common.Hash]common.Hash, []*types.Transaction, error) { | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	txHashMap := make(map[common.Hash]common.Hash, numTxs) | 
					
						
							|  |  |  | 	txs := make([]*types.Transaction, numTxs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	nextTx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if nextTx == nil { | 
					
						
							|  |  |  | 		return nil, nil, fmt.Errorf("failed to get the next transaction") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	gas := nextTx.Gas() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nonce = nonce + 1 | 
					
						
							|  |  |  | 	// generate txs | 
					
						
							|  |  |  | 	for i := 0; i < numTxs; i++ { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		tx := generateTx(s.chain.chainConfig, nonce, gas) | 
					
						
							|  |  |  | 		if tx == nil { | 
					
						
							|  |  |  | 			return nil, nil, fmt.Errorf("failed to get the next transaction") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 		txHashMap[tx.Hash()] = tx.Hash() | 
					
						
							|  |  |  | 		txs[i] = tx | 
					
						
							|  |  |  | 		nonce = nonce + 1 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return txHashMap, txs, nil | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func generateTx(chainConfig *params.ChainConfig, nonce uint64, gas uint64) *types.Transaction { | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	tx := types.NewTransaction(nonce, to, big.NewInt(1), gas, big.NewInt(1), []byte{}) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(chainConfig, tx) | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func getOldTxFromChain(s *Suite) *types.Transaction { | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	for _, blocks := range s.fullChain.blocks[:s.chain.Len()-1] { | 
					
						
							|  |  |  | 		txs := blocks.Transactions() | 
					
						
							|  |  |  | 		if txs.Len() != 0 { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			return txs[0] | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func invalidNonceTx(s *Suite) *types.Transaction { | 
					
						
							|  |  |  | 	tx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	if tx.To() != nil { | 
					
						
							|  |  |  | 		to = *tx.To() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	txNew := types.NewTransaction(tx.Nonce()-2, to, tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data()) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(s.chain.chainConfig, txNew) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func hugeAmount(s *Suite) *types.Transaction { | 
					
						
							|  |  |  | 	tx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	amount := largeNumber(2) | 
					
						
							|  |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	if tx.To() != nil { | 
					
						
							|  |  |  | 		to = *tx.To() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	txNew := types.NewTransaction(tx.Nonce(), to, amount, tx.Gas(), tx.GasPrice(), tx.Data()) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(s.chain.chainConfig, txNew) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func hugeGasPrice(s *Suite) *types.Transaction { | 
					
						
							|  |  |  | 	tx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	gasPrice := largeNumber(2) | 
					
						
							|  |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	if tx.To() != nil { | 
					
						
							|  |  |  | 		to = *tx.To() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	txNew := types.NewTransaction(tx.Nonce(), to, tx.Value(), tx.Gas(), gasPrice, tx.Data()) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(s.chain.chainConfig, txNew) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func hugeData(s *Suite) *types.Transaction { | 
					
						
							|  |  |  | 	tx := getNextTxFromChain(s) | 
					
						
							|  |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	var to common.Address | 
					
						
							|  |  |  | 	if tx.To() != nil { | 
					
						
							|  |  |  | 		to = *tx.To() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	txNew := types.NewTransaction(tx.Nonce(), to, tx.Value(), tx.Gas(), tx.GasPrice(), largeBuffer(2)) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	return signWithFaucet(s.chain.chainConfig, txNew) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | func signWithFaucet(chainConfig *params.ChainConfig, tx *types.Transaction) *types.Transaction { | 
					
						
							| 
									
										
										
										
											2021-04-23 18:14:39 +02:00
										 |  |  | 	signer := types.LatestSigner(chainConfig) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	signedTx, err := types.SignTx(tx, signer, faucetKey) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return signedTx | 
					
						
							|  |  |  | } |