@ -64,23 +64,23 @@ func NewSuite(dest *enode.Node, chainDir, engineURL, jwt string) (*Suite, error)
func ( s * Suite ) EthTests ( ) [ ] utesting . Test {
func ( s * Suite ) EthTests ( ) [ ] utesting . Test {
return [ ] utesting . Test {
return [ ] utesting . Test {
// status
// status
{ Name : "Test Status" , Fn : s . TestStatus } ,
{ Name : "Status" , Fn : s . TestStatus } ,
// get block headers
// get block headers
{ Name : "Test GetBlockHeaders" , Fn : s . TestGetBlockHeaders } ,
{ Name : "GetBlockHeaders" , Fn : s . TestGetBlockHeaders } ,
{ Name : "Test SimultaneousRequests" , Fn : s . TestSimultaneousRequests } ,
{ Name : "SimultaneousRequests" , Fn : s . TestSimultaneousRequests } ,
{ Name : "Test SameRequestID" , Fn : s . TestSameRequestID } ,
{ Name : "SameRequestID" , Fn : s . TestSameRequestID } ,
{ Name : "Test ZeroRequestID" , Fn : s . TestZeroRequestID } ,
{ Name : "ZeroRequestID" , Fn : s . TestZeroRequestID } ,
// get block bodies
// get block bodies
{ Name : "Test GetBlockBodies" , Fn : s . TestGetBlockBodies } ,
{ Name : "GetBlockBodies" , Fn : s . TestGetBlockBodies } ,
// // malicious handshakes + status
// // malicious handshakes + status
{ Name : "Test MaliciousHandshake" , Fn : s . TestMaliciousHandshake } ,
{ Name : "MaliciousHandshake" , Fn : s . TestMaliciousHandshake } ,
{ Name : "Test MaliciousStatus" , Fn : s . TestMaliciousStatus } ,
{ Name : "MaliciousStatus" , Fn : s . TestMaliciousStatus } ,
// test transactions
// test transactions
{ Name : "Test LargeTxRequest" , Fn : s . TestLargeTxRequest , Slow : true } ,
{ Name : "LargeTxRequest" , Fn : s . TestLargeTxRequest , Slow : true } ,
{ Name : "TestT ransaction" , Fn : s . TestTransaction } ,
{ Name : "Transaction" , Fn : s . TestTransaction } ,
{ Name : "Test InvalidTxs" , Fn : s . TestInvalidTxs } ,
{ Name : "InvalidTxs" , Fn : s . TestInvalidTxs } ,
{ Name : "Test NewPooledTxs" , Fn : s . TestNewPooledTxs } ,
{ Name : "NewPooledTxs" , Fn : s . TestNewPooledTxs } ,
{ Name : "Test BlobViolations" , Fn : s . TestBlobViolations } ,
{ Name : "BlobViolations" , Fn : s . TestBlobViolations } ,
}
}
}
}
@ -94,9 +94,9 @@ func (s *Suite) SnapTests() []utesting.Test {
}
}
}
}
// TestStatus attempts to connect to the given node and exchange a status
// message with it on the eth protocol.
func ( s * Suite ) TestStatus ( t * utesting . T ) {
func ( s * Suite ) TestStatus ( t * utesting . T ) {
t . Log ( ` This test is just a sanity check. It performs an eth protocol handshake. ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -112,9 +112,9 @@ func headersMatch(expected []*types.Header, headers []*types.Header) bool {
return reflect . DeepEqual ( expected , headers )
return reflect . DeepEqual ( expected , headers )
}
}
// TestGetBlockHeaders tests whether the given node can respond to an eth
// `GetBlockHeaders` request and that the response is accurate.
func ( s * Suite ) TestGetBlockHeaders ( t * utesting . T ) {
func ( s * Suite ) TestGetBlockHeaders ( t * utesting . T ) {
t . Log ( ` This test requests block headers from the node. ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -154,10 +154,10 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
}
}
}
}
// TestSimultaneousRequests sends two simultaneous `GetBlockHeader` requests
// from the same connection with different request IDs and checks to make sure
// the node responds with the correct headers per request.
func ( s * Suite ) TestSimultaneousRequests ( t * utesting . T ) {
func ( s * Suite ) TestSimultaneousRequests ( t * utesting . T ) {
t . Log ( ` This test requests blocks headers from the node , performing two requests
concurrently , with different request IDs . ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -228,9 +228,10 @@ func (s *Suite) TestSimultaneousRequests(t *utesting.T) {
}
}
}
}
// TestSameRequestID sends two requests with the same request ID to a single
// node.
func ( s * Suite ) TestSameRequestID ( t * utesting . T ) {
func ( s * Suite ) TestSameRequestID ( t * utesting . T ) {
t . Log ( ` This test requests block headers , performing two concurrent requests with the
same request ID . The node should handle the request by responding to both requests . ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -298,9 +299,10 @@ func (s *Suite) TestSameRequestID(t *utesting.T) {
}
}
}
}
// TestZeroRequestID checks that a message with a request ID of zero is still handled
// by the node.
func ( s * Suite ) TestZeroRequestID ( t * utesting . T ) {
func ( s * Suite ) TestZeroRequestID ( t * utesting . T ) {
t . Log ( ` This test sends a GetBlockHeaders message with a request - id of zero ,
and expects a response . ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -333,9 +335,9 @@ func (s *Suite) TestZeroRequestID(t *utesting.T) {
}
}
}
}
// TestGetBlockBodies tests whether the given node can respond to a
// `GetBlockBodies` request and that the response is accurate.
func ( s * Suite ) TestGetBlockBodies ( t * utesting . T ) {
func ( s * Suite ) TestGetBlockBodies ( t * utesting . T ) {
t . Log ( ` This test sends GetBlockBodies requests to the node for known blocks in the test chain. ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -376,12 +378,12 @@ func randBuf(size int) []byte {
return buf
return buf
}
}
// TestMaliciousHandshake tries to send malicious data during the handshake.
func ( s * Suite ) TestMaliciousHandshake ( t * utesting . T ) {
func ( s * Suite ) TestMaliciousHandshake ( t * utesting . T ) {
key , _ := crypto . GenerateKey ( )
t . Log ( ` This test tries to send malicious data during the devp2p handshake, in various ways. ` )
// Write hello to client.
// Write hello to client.
var (
var (
key , _ = crypto . GenerateKey ( )
pub0 = crypto . FromECDSAPub ( & key . PublicKey ) [ 1 : ]
pub0 = crypto . FromECDSAPub ( & key . PublicKey ) [ 1 : ]
version = eth . ProtocolVersions [ 0 ]
version = eth . ProtocolVersions [ 0 ]
)
)
@ -451,8 +453,9 @@ func (s *Suite) TestMaliciousHandshake(t *utesting.T) {
}
}
}
}
// TestMaliciousStatus sends a status package with a large total difficulty.
func ( s * Suite ) TestMaliciousStatus ( t * utesting . T ) {
func ( s * Suite ) TestMaliciousStatus ( t * utesting . T ) {
t . Log ( ` This test sends a malicious eth Status message to the node and expects a disconnect. ` )
conn , err := s . dial ( )
conn , err := s . dial ( )
if err != nil {
if err != nil {
t . Fatalf ( "dial failed: %v" , err )
t . Fatalf ( "dial failed: %v" , err )
@ -486,9 +489,10 @@ func (s *Suite) TestMaliciousStatus(t *utesting.T) {
}
}
}
}
// TestTransaction sends a valid transaction to the node and checks if the
// transaction gets propagated.
func ( s * Suite ) TestTransaction ( t * utesting . T ) {
func ( s * Suite ) TestTransaction ( t * utesting . T ) {
t . Log ( ` This test sends a valid transaction to the node and checks if the
transaction gets propagated . ` )
// Nudge client out of syncing mode to accept pending txs.
// Nudge client out of syncing mode to accept pending txs.
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
t . Fatalf ( "failed to send next block: %v" , err )
t . Fatalf ( "failed to send next block: %v" , err )
@ -507,15 +511,16 @@ func (s *Suite) TestTransaction(t *utesting.T) {
if err != nil {
if err != nil {
t . Fatalf ( "failed to sign tx: %v" , err )
t . Fatalf ( "failed to sign tx: %v" , err )
}
}
if err := s . sendTxs ( [ ] * types . Transaction { tx } ) ; err != nil {
if err := s . sendTxs ( t , [ ] * types . Transaction { tx } ) ; err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
s . chain . IncNonce ( from , 1 )
s . chain . IncNonce ( from , 1 )
}
}
// TestInvalidTxs sends several invalid transactions and tests whether
// the node will propagate them.
func ( s * Suite ) TestInvalidTxs ( t * utesting . T ) {
func ( s * Suite ) TestInvalidTxs ( t * utesting . T ) {
t . Log ( ` This test sends several kinds of invalid transactions and checks that the node
does not propagate them . ` )
// Nudge client out of syncing mode to accept pending txs.
// Nudge client out of syncing mode to accept pending txs.
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
t . Fatalf ( "failed to send next block: %v" , err )
t . Fatalf ( "failed to send next block: %v" , err )
@ -534,7 +539,7 @@ func (s *Suite) TestInvalidTxs(t *utesting.T) {
if err != nil {
if err != nil {
t . Fatalf ( "failed to sign tx: %v" , err )
t . Fatalf ( "failed to sign tx: %v" , err )
}
}
if err := s . sendTxs ( [ ] * types . Transaction { tx } ) ; err != nil {
if err := s . sendTxs ( t , [ ] * types . Transaction { tx } ) ; err != nil {
t . Fatalf ( "failed to send txs: %v" , err )
t . Fatalf ( "failed to send txs: %v" , err )
}
}
s . chain . IncNonce ( from , 1 )
s . chain . IncNonce ( from , 1 )
@ -590,14 +595,15 @@ func (s *Suite) TestInvalidTxs(t *utesting.T) {
}
}
txs = append ( txs , tx )
txs = append ( txs , tx )
}
}
if err := s . sendInvalidTxs ( txs ) ; err != nil {
if err := s . sendInvalidTxs ( t , t xs) ; err != nil {
t . Fatalf ( "failed to send invalid txs: %v" , err )
t . Fatalf ( "failed to send invalid txs: %v" , err )
}
}
}
}
// TestLargeTxRequest tests whether a node can fulfill a large GetPooledTransactions
// request.
func ( s * Suite ) TestLargeTxRequest ( t * utesting . T ) {
func ( s * Suite ) TestLargeTxRequest ( t * utesting . T ) {
t . Log ( ` This test first send ~ 2000 transactions to the node , then requests them
on another peer connection using GetPooledTransactions . ` )
// Nudge client out of syncing mode to accept pending txs.
// Nudge client out of syncing mode to accept pending txs.
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
t . Fatalf ( "failed to send next block: %v" , err )
t . Fatalf ( "failed to send next block: %v" , err )
@ -630,7 +636,7 @@ func (s *Suite) TestLargeTxRequest(t *utesting.T) {
s . chain . IncNonce ( from , uint64 ( count ) )
s . chain . IncNonce ( from , uint64 ( count ) )
// Send txs.
// Send txs.
if err := s . sendTxs ( txs ) ; err != nil {
if err := s . sendTxs ( t , t xs) ; err != nil {
t . Fatalf ( "failed to send txs: %v" , err )
t . Fatalf ( "failed to send txs: %v" , err )
}
}
@ -667,13 +673,15 @@ func (s *Suite) TestLargeTxRequest(t *utesting.T) {
}
}
}
}
// TestNewPooledTxs tests whether a node will do a GetPooledTransactions request
// upon receiving a NewPooledTransactionHashes announcement.
func ( s * Suite ) TestNewPooledTxs ( t * utesting . T ) {
func ( s * Suite ) TestNewPooledTxs ( t * utesting . T ) {
t . Log ( ` This test announces transaction hashes to the node and expects it to fetch
the transactions using a GetPooledTransactions request . ` )
// Nudge client out of syncing mode to accept pending txs.
// Nudge client out of syncing mode to accept pending txs.
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
t . Fatalf ( "failed to send next block: %v" , err )
t . Fatalf ( "failed to send next block: %v" , err )
}
}
var (
var (
count = 50
count = 50
from , nonce = s . chain . GetSender ( 1 )
from , nonce = s . chain . GetSender ( 1 )
@ -787,6 +795,8 @@ func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Tra
}
}
func ( s * Suite ) TestBlobViolations ( t * utesting . T ) {
func ( s * Suite ) TestBlobViolations ( t * utesting . T ) {
t . Log ( ` This test sends some invalid blob tx announcements and expects the node to disconnect. ` )
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
if err := s . engine . sendForkchoiceUpdated ( ) ; err != nil {
t . Fatalf ( "send fcu failed: %v" , err )
t . Fatalf ( "send fcu failed: %v" , err )
}
}