4.3 Code Geth Transaction Pool
The Protocol 'eth'#
While the token on Ethereum has the code ETH, the protocol that the execution client uses to sync transactions is also called 'ETH', with its full name being 'Ethereum Wire Protocol' according to the devp2p specs here. I will focus on its 'transaction exchange'.
Receiving A Transaction from A Wallet through JSON-RPC#
When a call arrives at eth_sendTransaction
endpoint, its handled by func SendTransaction
in https://github.com/ethereum/go-ethereum/blob/v1.11.2/internal/ethapi/api.go L:1722
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
// transaction pool.
func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) {
//...
return SubmitTransaction(ctx, s.b, signed)
}
// ...
// SubmitTransaction is a helper function that submits tx to txPool and logs a message.
func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) {
// ...
if err := b.SendTx(ctx, tx); err != nil {
return common.Hash{}, err
}
// ...
return tx.Hash(), nil
}
SendTx
adds the transaction to the local transaction pool. The transaction pool txPool
will communicate the new transaction to the other peers. In https://github.com/ethereum/go-ethereum/blob/v1.11.2/eth/api_backend.go L:261
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
return b.eth.txPool.AddLocal(signedTx)
}
Receiving A Transaction from A Peer#
In https://github.com/ethereum/go-ethereum/blob/v1.11.2/eth/protocols/eth/handlers.go:
func handleNewPooledTransactionHashes68(backend Backend, msg Decoder, peer *Peer) error {
// ...
ann := new(NewPooledTransactionHashesPacket68)
// ...
// Schedule all the unknown hashes for retrieval
for _, hash := range ann.Hashes {
peer.markTransaction(hash)
}
return backend.Handle(peer, ann)
}
Where func Handle
in https://github.com/ethereum/go-ethereum/blob/v1.11.2/eth/handler_eth.go:
func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
case *eth.NewPooledTransactionHashesPacket68:
return h.txFetcher.Notify(peer.ID(), packet.Hashes)
}
where
txFetcher
fetches unknown transactions periodically from peers.
eth/66, eth/68, etc
eth/66 or eth/68 is code for devp2p upgrades. They are also mentioned in the protocol changelog here. In the code, they show up as suffix of function names, e.g. NewPooledTransactionHashesPacket68
or NewPooledTransactionHashesPacket66
.
Tell The Transaction to (More) Peers#
The code is found in the folder 'eth/protocols/eth', which is the protocol name. It is initialized in https://github.com/ethereum/go-ethereum/blob/v1.11.2/eth/protocols/eth/peer.go:
func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Peer {
// ...
go peer.announceTransactions()
// ...
return peer
}
where
peer
is representing a p2p connection to one other node. announceTransactions
is implemented in https://github.com/ethereum/go-ethereum/blob/v1.11.2/eth/protocols/eth/peer.go, and eventually calls p2p.Send()
to send NewPooledTransactionHashes(0x08)
, as said in the spec.
As the function name 'announce' suggest, this message does not send the real transaction. If the node thinks it's probably a new transaction, it will first announce it; if the peer does not have the transaction, the peer will ask for it; only then the node will send the transaction.
About Block Communication#
The spec also includes block communication, which is now taken over by the consensus client as discussed in 3.5 Code - Lodestar - Block Building.