Skip to content

Sync upstream v11.2.1 (merge conflicts)#76

Open
JOY (JOY) wants to merge 96 commits into
mainfrom
sync-upstream-v11.2.1
Open

Sync upstream v11.2.1 (merge conflicts)#76
JOY (JOY) wants to merge 96 commits into
mainfrom
sync-upstream-v11.2.1

Conversation

@JOY

Copy link
Copy Markdown

Upstream Sync - v11.2.1

Auto-merge with upstream v11.2.1 failed. Version/workflow conflicts were auto-resolved,
but the following files have code conflicts that need manual resolution:

docker-compose/envs/common-blockscout.env

To resolve:

  1. Check out this branch locally
  2. Resolve remaining conflicts
  3. Push and merge this PR
  4. Then create tag v11.2.1 to trigger Docker build

Upstream release notes

Alexander Kolotov (akolotov) and others added 30 commits May 8, 2026 18:45
Co-authored-by: Alexander Kolotov <alexander.kolotov@gmail.com>
Co-authored-by: Maxim Filonov <53992153+sl1depengwyn@users.noreply.github.com>
Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com>
…oints (blockscout#14227)

Co-authored-by: Alexander Kolotov <alexander.kolotov@gmail.com>
Co-authored-by: Maxim Filonov <53992153+sl1depengwyn@users.noreply.github.com>
Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com>
…ut#14251)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Alexander Kolotov <alexander.kolotov@gmail.com>
Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nikita Pozdniakov <nikitosing4@mail.ru>
Co-authored-by: Maxim Filonov <53992153+sl1depengwyn@users.noreply.github.com>
Co-authored-by: Qwerty5Uiop <alex000010@bk.ru>
Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#14350)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…CY (blockscout#14390)

Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Qwerty5Uiop and others added 27 commits June 11, 2026 18:37
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…4473)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…lockscout#14433)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Comment on lines +9 to +18
name: Resolve dev package version
runs-on: ubuntu-latest
outputs:
package_version: ${{ steps.set.outputs.package_version }}
steps:
- name: Set version from commit SHA
id: set
run: echo "package_version=v0.0.1-beta.${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

publish:
Comment on lines +19 to +25
name: Build and publish
needs: version
uses: ./.github/workflows/publish-api-types-npm.yml
with:
package_version: ${{ needs.version.outputs.package_version }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces comprehensive OpenAPI specifications for the Arbitrum and Advanced Filter endpoints, optimizes real-time event broadcasting in the Notifier by pre-filtering on active subscribers, and adds architectural guidelines for separate API/Indexer modes. However, several critical issues were identified during the review: the new subscriber-filtering logic in Notifier relies on node-local registry lookups which will silently drop real-time updates in distributed deployments, and it publishes un-preloaded token transfers to Absinthe subscriptions, risking N+1 queries or errors. Additionally, the list_methods action in AdvancedFilterController will crash when the optional q parameter is omitted, and globally dropping :batch_numbers in PagingHelper breaks pagination for the public Arbitrum batches endpoint.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +920 to +931
defp has_subscribers?(topic) when is_binary(topic) do
Registry.lookup(BlockScoutWeb.PubSub, topic) != []
end

defp address_has_subscribers?(nil), do: false

defp address_has_subscribers?(address_hash) do
hash_string = to_string(address_hash)

has_subscribers?("addresses:" <> hash_string) or
has_subscribers?("addresses_old:" <> hash_string)
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Registry.lookup/2 is node-local and only queries the registry of the current Erlang node. In a distributed or split-process deployment (such as running separate api and indexer instances, or multiple clustered api nodes behind a load balancer), clients subscribed to WebSocket topics on other nodes will not be visible to the node running the Notifier. As a result, address_has_subscribers?/1 will return false on publishing nodes, causing real-time updates (coin balances, token balances, transactions, token transfers) to be silently dropped for those clients.\n\nTo fix this, you should avoid filtering broadcasts at the publisher side using local registry lookups, or use a distributed tracking mechanism (like Erlang's :pg groups or Phoenix Tracker) if pre-filtering is absolutely necessary for performance.

Comment on lines 280 to +290
def handle_event({:chain_event, :token_transfers, :realtime, all_token_transfers}) do
all_token_transfers_full =
all_token_transfers
|> Repo.preload(
DenormalizationHelper.extend_transaction_preload([
[token: Reputation.reputation_association()],
:transaction,
from_address: [
:scam_badge,
:names,
:smart_contract,
proxy_implementations_association()
],
to_address: [
:scam_badge,
:names,
:smart_contract,
proxy_implementations_association()
]
])
)
|> Instance.preload_nft(@api_true)

transfers_by_token = Enum.group_by(all_token_transfers_full, fn tt -> to_string(tt.token_contract_address_hash) end)

broadcast_token_transfers_websocket_v2(all_token_transfers_full, transfers_by_token)
all_transfers_by_token =
Enum.group_by(all_token_transfers, fn tt -> to_string(tt.token_contract_address_hash) end)

for {token_contract_address_hash, token_transfers} <- transfers_by_token do
for {token_contract_address_hash, token_transfers} <- all_transfers_by_token do
Subscription.publish(
Endpoint,
token_transfers,
token_transfers: token_contract_address_hash
)
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In the refactored handle_event/1 for :token_transfers, Subscription.publish/3 is called with token_transfers grouped from all_token_transfers instead of all_token_transfers_full. Unlike all_token_transfers_full, all_token_transfers does not have any preloaded associations (such as :token, :transaction, :from_address, :to_address).\n\nWhen Absinthe attempts to resolve fields on these un-preloaded associations for active GraphQL subscription clients, it will either return Ecto.Association.NotLoaded structs (resulting in empty/null fields or errors) or trigger massive N+1 database queries.\n\nTo resolve this, ensure that the token transfers published to Absinthe are fully preloaded.

Comment on lines +422 to +423
@spec list_methods(Plug.Conn.t(), map()) :: Plug.Conn.t()
def list_methods(conn, %{q: query}) when is_binary(query) do

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The list_methods/2 action is defined with a single clause matching %{q: query} when is_binary(query). However, the :q parameter is declared as optional (required: false) in the operation :list_methods spec, and the description states: "Without q, returns the default list of popular methods."\n\nIf a client requests this endpoint without the q query parameter, the pattern match will fail, causing the request to crash with a FunctionClauseError.\n\nPlease add a fallback clause to handle the absence of q and return the default list of popular methods.

Comment on lines 263 to 273
|> Map.drop([
:address_hash_param,
:batch_number_param,
:batch_numbers,
:data_hash,
:block_hash_or_number_param,
:direction,
:transaction_hash_param,
:batch_number_param,
:scale,
:token_id_param,
:token_id,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Adding :batch_numbers to the global Map.drop list in delete_parameters_from_next_page_params/1 will strip the batch_numbers query parameter from the generated next_page_params cursor.\n\nWhile this prevents validation errors on the DA-specific endpoints (which don't declare :batch_numbers in their specs), it completely breaks pagination for the public GET /api/v2/arbitrum/batches endpoint. If a client filters batches by batch_numbers and requests the next page, the filter will be lost, and subsequent pages will return all batches instead of the filtered subset.\n\nTo fix this, avoid dropping :batch_numbers globally. Instead, either handle the exclusion specifically for the DA endpoints in the controller, or declare :batch_numbers as an optional parameter on those endpoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants