mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-15 04:26:37 +00:00
cmd/devp2p: add duplicated pooled txs
This commit is contained in:
parent
cb697a4b3e
commit
107f54a05d
2 changed files with 94 additions and 0 deletions
|
|
@ -91,6 +91,7 @@ func (s *Suite) EthTests() []utesting.Test {
|
||||||
{Name: "TestBlobTxWithoutSidecar", Fn: s.TestBlobTxWithoutSidecar},
|
{Name: "TestBlobTxWithoutSidecar", Fn: s.TestBlobTxWithoutSidecar},
|
||||||
{Name: "TestBlobTxWithMismatchedSidecar", Fn: s.TestBlobTxWithMismatchedSidecar},
|
{Name: "TestBlobTxWithMismatchedSidecar", Fn: s.TestBlobTxWithMismatchedSidecar},
|
||||||
{Name: "DuplicateTxs", Fn: s.TestDuplicateTxs},
|
{Name: "DuplicateTxs", Fn: s.TestDuplicateTxs},
|
||||||
|
{Name: "DuplicatePooledTxs", Fn: s.TestDuplicatePooledTxs},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1217,3 +1218,33 @@ func (s *Suite) TestDuplicateTxs(t *utesting.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Suite) TestDuplicatePooledTxs(t *utesting.T) {
|
||||||
|
t.Log(`This test announces transaction hashes to the node, then sends a PooledTransactionsMsg containing duplicate transactions and expects the node to disconnect.`)
|
||||||
|
|
||||||
|
// Nudge client out of syncing mode to accept pending txs.
|
||||||
|
if err := s.engine.sendForkchoiceUpdated(); err != nil {
|
||||||
|
t.Fatalf("failed to send next block: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
from, nonce := s.chain.GetSender(1)
|
||||||
|
inner := &types.DynamicFeeTx{
|
||||||
|
ChainID: s.chain.config.ChainID,
|
||||||
|
Nonce: nonce,
|
||||||
|
GasTipCap: common.Big1,
|
||||||
|
GasFeeCap: s.chain.Head().BaseFee(),
|
||||||
|
Gas: 75000,
|
||||||
|
To: &common.Address{0xbb},
|
||||||
|
Value: common.Big1,
|
||||||
|
}
|
||||||
|
tx, err := s.chain.SignTx(from, types.NewTx(inner))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to sign tx: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the same transaction twice in the PooledTransactionsMsg.
|
||||||
|
txs := []*types.Transaction{tx, tx}
|
||||||
|
if err := s.sendDuplicatePooledTxsInOneMsg(t, txs); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,3 +204,66 @@ func (s *Suite) sendDuplicateTxsInOneMsg(t *utesting.T, txs []*types.Transaction
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sendDuplicatePooledTxsInOneMsg sends a PooledTransactionsMsg containing duplicates
|
||||||
|
// and expects the node to disconnect.
|
||||||
|
func (s *Suite) sendDuplicatePooledTxsInOneMsg(t *utesting.T, txs []*types.Transaction) error {
|
||||||
|
// First, announce the transactions so the node will request them.
|
||||||
|
announceConn, err := s.dial()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dial failed: %v", err)
|
||||||
|
}
|
||||||
|
defer announceConn.Close()
|
||||||
|
|
||||||
|
if err = announceConn.peer(s.chain, nil); err != nil {
|
||||||
|
return fmt.Errorf("peering failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create announcement for the transactions.
|
||||||
|
var (
|
||||||
|
hashes = make([]common.Hash, len(txs))
|
||||||
|
types = make([]byte, len(txs))
|
||||||
|
sizes = make([]uint32, len(txs))
|
||||||
|
)
|
||||||
|
for i, tx := range txs {
|
||||||
|
hashes[i] = tx.Hash()
|
||||||
|
types[i] = tx.Type()
|
||||||
|
sizes[i] = uint32(tx.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
ann := eth.NewPooledTransactionHashesPacket{
|
||||||
|
Types: types,
|
||||||
|
Sizes: sizes,
|
||||||
|
Hashes: hashes,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := announceConn.Write(ethProto, eth.NewPooledTransactionHashesMsg, ann); err != nil {
|
||||||
|
return fmt.Errorf("failed to announce transactions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for GetPooledTransactions request.
|
||||||
|
req := new(eth.GetPooledTransactionsPacket)
|
||||||
|
if err := announceConn.ReadMsg(ethProto, eth.GetPooledTransactionsMsg, req); err != nil {
|
||||||
|
return fmt.Errorf("failed to read GetPooledTransactions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send response with duplicate transactions.
|
||||||
|
resp := ð.PooledTransactionsPacket{
|
||||||
|
RequestId: req.RequestId,
|
||||||
|
PooledTransactionsResponse: eth.PooledTransactionsResponse(txs),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := announceConn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil {
|
||||||
|
return fmt.Errorf("failed to send PooledTransactions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expect disconnect.
|
||||||
|
code, _, err := announceConn.Read()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading from connection: %v", err)
|
||||||
|
}
|
||||||
|
if code != discMsg {
|
||||||
|
return fmt.Errorf("expected disconnect, got msg code %d", code)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue