diff --git a/internal/rpc/solana/client.go b/internal/rpc/solana/client.go index e919d2c..c5ffde6 100644 --- a/internal/rpc/solana/client.go +++ b/internal/rpc/solana/client.go @@ -53,7 +53,7 @@ func (c *Client) GetSlot(ctx context.Context) (uint64, error) { func (c *Client) GetTransaction(ctx context.Context, signature string) (*GetTransactionResult, error) { cfg := map[string]any{ "encoding": "jsonParsed", - "maxSupportedTransactionVersion": 0, + "maxSupportedTransactionVersion": MaxSupportedTransactionVersion, "commitment": "finalized", } resp, err := c.base.CallRPC(ctx, "getTransaction", []any{signature, cfg}) @@ -78,7 +78,7 @@ func (c *Client) GetBlock(ctx context.Context, slot uint64) (*GetBlockResult, er Encoding: "jsonParsed", TransactionDetails: "full", Rewards: false, - MaxSupportedTransactionVersion: 0, + MaxSupportedTransactionVersion: MaxSupportedTransactionVersion, Commitment: "finalized", } resp, err := c.base.CallRPC(ctx, "getBlock", []any{slot, cfg}) diff --git a/internal/rpc/solana/types.go b/internal/rpc/solana/types.go index 8db5c51..979067e 100644 --- a/internal/rpc/solana/types.go +++ b/internal/rpc/solana/types.go @@ -23,11 +23,17 @@ type jsonRPCError struct { type GetSlotResult uint64 +// MaxSupportedTransactionVersion is the newest transaction format getBlock and getTransaction may return. +// Clusters now include version 1 transactions in most blocks; asking for at most 0 makes the RPC reject the +// whole block ("Transaction version (1) is not supported by the requesting client"). Version 1 parses like +// version 0 for transfers (it adds a transactionConfig field and drops addressTableLookups). +const MaxSupportedTransactionVersion = 1 + type GetBlockConfig struct { Encoding string `json:"encoding"` // json | jsonParsed TransactionDetails string `json:"transactionDetails"` // full Rewards bool `json:"rewards"` // false - MaxSupportedTransactionVersion int `json:"maxSupportedTransactionVersion"` // 0 + MaxSupportedTransactionVersion int `json:"maxSupportedTransactionVersion"` // MaxSupportedTransactionVersion Commitment string `json:"commitment,omitempty"` // processed | confirmed | finalized } diff --git a/pkg/addressbloomfilter/redis.go b/pkg/addressbloomfilter/redis.go index f5a1351..57ff821 100644 --- a/pkg/addressbloomfilter/redis.go +++ b/pkg/addressbloomfilter/redis.go @@ -214,13 +214,24 @@ func (rbf *redisBloomFilter) ContainsBatch(addresses []string, addressType enum. return results } for i, item := range items { - if n, ok := item.(int64); ok { - results[i] = n == 1 - } + results[i] = bloomReplyTrue(item) } return results } +// bloomReplyTrue reads one BF.MEXISTS reply item. RESP2 answers 1 or 0; RESP3, go-redis v9's default protocol, +// answers true or false. Reading only integers would report every address as unwatched. +func bloomReplyTrue(item any) bool { + switch v := item.(type) { + case int64: + return v == 1 + case bool: + return v + default: + return false + } +} + func (rbf *redisBloomFilter) Clear(addressType enum.NetworkType) { rbf.mu.Lock() defer rbf.mu.Unlock() diff --git a/pkg/addressbloomfilter/redis_reply_test.go b/pkg/addressbloomfilter/redis_reply_test.go new file mode 100644 index 0000000..630482e --- /dev/null +++ b/pkg/addressbloomfilter/redis_reply_test.go @@ -0,0 +1,22 @@ +package addressbloomfilter + +import "testing" + +func TestBloomReplyTrue_AcceptsResp2AndResp3Replies(t *testing.T) { + cases := []struct { + item any + want bool + }{ + {int64(1), true}, // RESP2 + {int64(0), false}, // RESP2 + {true, true}, // RESP3 + {false, false}, // RESP3 + {"1", false}, + {nil, false}, + } + for _, c := range cases { + if got := bloomReplyTrue(c.item); got != c.want { + t.Errorf("bloomReplyTrue(%#v) = %v, want %v", c.item, got, c.want) + } + } +}