Skip to content

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.