I am trying to get the pending transactions logs to identify specifics topics before the next block was mined (ERC20 transfers, Uniswap swaps, ..).

I run a Geth (1.9.22) full node, mining is enabled (by the way, it is not documented that it is necessary to activate mining to have a pending block), so I have an updated pending block every 2sec as I defined by --miner.recommit.

I am dealing with the JSON-RPC interface of my node with a Go client using go-ethereum libraries.

I correctly obtain the list of transactions present in the pending block :

RPCClient, _ = rpc.DialContext(context.Background(), MyNodeURI)

type rpcBlock struct {
    Transactions []RPCTransaction `json:"transactions"`

func GetPendingBlockTxs() ([]RPCTransaction, error){
    var raw json.RawMessage
    if err := RPCClient.CallContext(context.Background(), &raw, "eth_getBlockByNumber", "pending", true); err != nil {
        return []RPCTransaction{}, err
    var body rpcBlock
    if err := json.Unmarshal(raw, &body); err != nil {
        return []RPCTransaction{}, err
    return body.Transactions, nil

However, eth_getTransactionReceipt return not found for these transactions hashes, and I cant get how to use these transactions within eth_getLogs parameters.

Using eth_getLogs with just "pending" or "earliest" as fromBlock and toBlock parameters returns an empty array, it does not seem to me that this is a formatting problem since with "latest" I get what I ask for. So I guess I wouldn't have more success with eth_getFilterLogs (am I wrong ?).

Is there a method to get the logs (topics) of a transaction from the pending block that has not yet been mined? Maybe I'm wrong, but I know DEX front-runners use this kind of method. I'm starting to doubt that this is possible with a geth node.

Thank you for your time


Msg: {"jsonrpc":"2.0","id":1,"method":"eth_newFilter","params":[{"fromBlock":"pending","toBlock":"pending"}]}
Output: {"jsonrpc":"2.0","id":1,"result":"0xf6f0dd31d45f2bfea4c18c24cf424734"}

Msg: {"jsonrpc":"2.0","id":2,"method":"eth_getFilterChanges","params":["0xf6f0dd31d45f2bfea4c18c24cf424734"]}
Output: {"jsonrpc":"2.0","id":2,"result":[]}

Msg: {"jsonrpc":"2.0","id":1,"method":"eth_newFilter","params":[{"fromBlock":"pending","toBlock":"pending"}]}
Output: {"jsonrpc":"2.0","id":1,"result":"0xd8a295411c08771804312611f2220108"}

Msg: {"jsonrpc":"2.0","id":2,"method":"eth_getFilterLogs","params":["0xd8a295411c08771804312611f2220108"]}
Output: {"jsonrpc":"2.0","id":2,"result":[]}

getFilterLogs and getFilterChanges doesnt return the expected result.

edit2: According to this old answer, it should be possible, but it doesnt. I am trying to implement a custom endpoint to my geth node.


Finally, I found a way to achieve this by implementing a custom endpoint in the eth namespace API of geth (and so recompiling it from sources):

# .\go-ethereum\internal\ethapi\api.go ->
func (s *PublicBlockChainAPI) GetPendingLogs(ctx context.Context) ([]*types.Log, error) {
    state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber))
    if state == nil || err != nil {
        return nil, err
    return state.Logs(), state.Error()

Remember that this data is ephemeral and is only an estimate of what the next block might contain.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.