Skip to content

cmd/devp2p: ethtest suite runnable as unit test #22698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions cmd/devp2p/internal/ethtest/eth66_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,17 +351,15 @@ func (s *Suite) TestTransaction_66(t *utesting.T) {
}

func (s *Suite) TestMaliciousTx_66(t *utesting.T) {
tests := []*types.Transaction{
badTxs := []*types.Transaction{
getOldTxFromChain(t, s),
invalidNonceTx(t, s),
hugeAmount(t, s),
hugeGasPrice(t, s),
hugeData(t, s),
}
for i, tx := range tests {
t.Logf("Testing malicious tx propagation: %v\n", i)
sendFailingTx66(t, s, tx)
}
t.Logf("Testing malicious tx propagation")
sendFailingTx66(t, s, badTxs)
}

// TestZeroRequestID_66 checks that a request ID of zero is still handled
Expand Down
4 changes: 2 additions & 2 deletions cmd/devp2p/internal/ethtest/eth66_suiteHelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ func sendSuccessfulTx66(t *utesting.T, s *Suite, tx *types.Transaction) {
sendSuccessfulTxWithConn(t, s, tx, sendConn)
}

func sendFailingTx66(t *utesting.T, s *Suite, tx *types.Transaction) {
func sendFailingTx66(t *utesting.T, s *Suite, txs []*types.Transaction) {
sendConn, recvConn := s.setupConnection66(t), s.setupConnection66(t)
defer sendConn.Close()
defer recvConn.Close()
sendFailingTxWithConns(t, s, tx, sendConn, recvConn)
sendFailingTxsWithConns(t, s, txs, sendConn, recvConn)
}

func (s *Suite) getBlockHeaders66(t *utesting.T, conn *Conn, req eth.Packet, expectedID uint64) BlockHeaders {
Expand Down
8 changes: 3 additions & 5 deletions cmd/devp2p/internal/ethtest/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,15 +518,13 @@ func (s *Suite) TestTransaction(t *utesting.T) {
}

func (s *Suite) TestMaliciousTx(t *utesting.T) {
tests := []*types.Transaction{
badTxs := []*types.Transaction{
getOldTxFromChain(t, s),
invalidNonceTx(t, s),
hugeAmount(t, s),
hugeGasPrice(t, s),
hugeData(t, s),
}
for i, tx := range tests {
t.Logf("Testing malicious tx propagation: %v\n", i)
sendFailingTx(t, s, tx)
}
t.Logf("Testing malicious tx propagation")
sendFailingTxs(t, s, badTxs)
}
53 changes: 39 additions & 14 deletions cmd/devp2p/internal/ethtest/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,42 @@ func sendSuccessfulTxWithConn(t *utesting.T, s *Suite, tx *types.Transaction, se
}
}

func sendFailingTx(t *utesting.T, s *Suite, tx *types.Transaction) {
func sendFailingTxs(t *utesting.T, s *Suite, txs []*types.Transaction) {
sendConn, recvConn := s.setupConnection(t), s.setupConnection(t)
defer sendConn.Close()
defer recvConn.Close()
sendFailingTxWithConns(t, s, tx, sendConn, recvConn)
sendFailingTxsWithConns(t, s, txs, sendConn, recvConn)
}

func sendFailingTxWithConns(t *utesting.T, s *Suite, tx *types.Transaction, sendConn, recvConn *Conn) {
// Wait for a transaction announcement
switch msg := recvConn.ReadAndServe(s.chain, timeout).(type) {
case *NewPooledTransactionHashes:
break
default:
t.Logf("unexpected message, logging: %v", pretty.Sdump(msg))
}
func sendFailingTxsWithConns(t *utesting.T, s *Suite, txs []*types.Transaction, sendConn, recvConn *Conn) {
// Send the transaction
if err := sendConn.Write(&Transactions{tx}); err != nil {
txMsg := Transactions(txs)
if err := sendConn.Write(&txMsg); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should announce the txs individually here. Some of them can be large, and the node might reject the entire announcement when the first item is too big.

Copy link
Contributor

@fjl fjl Apr 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is, you can just send them in a loop like

for _, tx := range txs {
    if err := sendConn.Write(&Transactions{tx}); err != nil { ... }
}

t.Fatal(err)
}
// Wait for another transaction announcement
switch msg := recvConn.ReadAndServe(s.chain, timeout).(type) {
switch msg := recvConn.ReadAndServe(s.chain, time.Second * 8).(type) {
case *Transactions:
t.Fatalf("Received unexpected transaction announcement: %v", msg)
// 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()
}
badTxs := containsTxs(recvTxs, txs)
if len(badTxs) > 0 {
for _, tx := range badTxs {
t.Logf("received bad tx: %v", tx)
}
t.Fatalf("received %d bad txs", len(badTxs))
}
case *NewPooledTransactionHashes:
t.Fatalf("Received unexpected pooledTx announcement: %v", msg)
badTxs := containsTxs(*msg, txs)
if len(badTxs) > 0 {
for _, tx := range badTxs {
t.Logf("received bad tx: %v", tx)
}
t.Fatalf("received %d bad txs", len(badTxs))
}
case *Error:
// Transaction should not be announced -> wait for timeout
return
Expand All @@ -99,6 +110,20 @@ func sendFailingTxWithConns(t *utesting.T, s *Suite, tx *types.Transaction, send
}
}

// containsTxs checks whether the hashes of the received transactions are present in
// the given set of txs
func containsTxs(recvTxs []common.Hash, txs []*types.Transaction, ) []common.Hash {
containedTxs := make([]common.Hash, 0)
for _, recvTx := range recvTxs {
for _, tx := range txs {
if recvTx == tx.Hash() {
containedTxs = append(containedTxs, recvTx)
}
}
}
return containedTxs
}

func unknownTx(t *utesting.T, s *Suite) *types.Transaction {
tx := getNextTxFromChain(t, s)
var to common.Address
Expand Down