From c638faaf34326689defe04df6aa023fade0f8fea Mon Sep 17 00:00:00 2001 From: locoholy Date: Tue, 24 Feb 2026 11:49:25 +0500 Subject: [PATCH] ethclient: omit empty address filter field in toFilterArg Previously, an empty (non-nil) []common.Address{} slice caused the "address" field to be serialized as an empty JSON array [] in the RPC request. Some Ethereum-compatible nodes (e.g. Hedera) reject this empty array with an error. According to the JSON-RPC specification the "address" field is optional. Align with the spec by only including the field when at least one address is present, treating []Address{} the same as nil. Add a test case "with empty addresses slice" to TestToFilterArg to prevent regression. --- ethclient/ethclient.go | 6 +++++- ethclient/types_test.go | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index bc4eaad6fa..3fdde6978b 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -498,7 +498,11 @@ func (ec *Client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuer func toFilterArg(q ethereum.FilterQuery) (interface{}, error) { arg := map[string]interface{}{} - if q.Addresses != nil { + // Only include "address" when there are actual address filters. + // An empty slice is treated the same as nil (no filter), and omitting + // the field avoids sending "address":[] to nodes that reject empty arrays + // (e.g. Hedera, some non-Geth implementations). + if len(q.Addresses) > 0 { arg["address"] = q.Addresses } if q.Topics != nil { diff --git a/ethclient/types_test.go b/ethclient/types_test.go index dcb9a579b7..8820b11162 100644 --- a/ethclient/types_test.go +++ b/ethclient/types_test.go @@ -53,6 +53,22 @@ func TestToFilterArg(t *testing.T) { }, nil, }, + { + // empty Addresses slice must be treated same as nil: + // the "address" field must be omitted so that non-Geth nodes + // (e.g. Hedera) do not reject the request with an error. + "with empty addresses slice", + ethereum.FilterQuery{ + Addresses: []common.Address{}, + FromBlock: big.NewInt(1), + ToBlock: big.NewInt(2), + }, + map[string]interface{}{ + "fromBlock": "0x1", + "toBlock": "0x2", + }, + nil, + }, { "without BlockHash", ethereum.FilterQuery{