Skip to content

Commit

Permalink
Fix duplicate read methods (blockscout#9591)
Browse files Browse the repository at this point in the history
* Fix the typo in docs

* Fix duplicated results in `methods-read` endpoint

* Add regression test ensuring read-methods are not duplicated

* Update `CHANGELOG.md`
  • Loading branch information
fedor-ivn authored Mar 12, 2024
1 parent eac1bcd commit 354b7e4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

### Fixes

- [#9591](https://github.com/blockscout/blockscout/pull/9591) - Fix duplicated results in `methods-read` endpoint
- [#9502](https://github.com/blockscout/blockscout/pull/9502) - Add batch_size and concurrency envs for tt token type migration
- [#9493](https://github.com/blockscout/blockscout/pull/9493) - Fix API response for unknown blob hashes
- [#9484](https://github.com/blockscout/blockscout/pull/9484) - Fix read contract error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,64 @@ defmodule BlockScoutWeb.API.V2.SmartContractControllerTest do
refute %{"type" => "receive"} in response
end

test "ensure read-methods are not duplicated", %{conn: conn} do
abi = [
%{
"inputs" => [],
"name" => "test",
"outputs" => [
%{"internalType" => "uint256", "name" => "", "type" => "uint256"}
],
"stateMutability" => "pure",
"type" => "function"
}
]

id =
abi
|> ABI.parse_specification()
|> Enum.at(0)
|> Map.fetch!(:method_id)

target_contract = insert(:smart_contract, abi: abi)

expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn [%{id: id, method: "eth_call", params: _params}], _opts ->
{:ok,
[
%{
id: id,
jsonrpc: "2.0",
result: "0x00000000000000000000000000000000000000000000009d37020ac9049a8040"
}
]}
end
)

request = get(conn, "/api/v2/smart-contracts/#{target_contract.address_hash}/methods-read")

assert response = json_response(request, 200)

assert response == [
%{
"type" => "function",
"stateMutability" => "pure",
"outputs" => [
%{
"type" => "uint256",
"value" => 2_900_102_562_052_921_000_000
}
],
"name" => "test",
"names" => ["uint256"],
"inputs" => [],
"method_id" => Base.encode16(id, case: :lower)
}
]
end

test "get array of addresses within read-methods", %{conn: conn} do
abi = [
%{
Expand Down
3 changes: 2 additions & 1 deletion apps/explorer/lib/explorer/smart_contract/helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ defmodule Explorer.SmartContract.Helper do
def error?(function), do: function["type"] == "error"

@doc """
Checks whether the function which is not queriable can be consider as read function or not.
Checks whether the function which is not queriable can be considered as read
function or not.
"""
@spec read_with_wallet_method?(%{}) :: true | false
def read_with_wallet_method?(function),
Expand Down
1 change: 1 addition & 0 deletions apps/explorer/lib/explorer/smart_contract/reader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ defmodule Explorer.SmartContract.Reader do
abi_with_method_id = get_abi_with_method_id(abi)

abi_with_method_id
|> Enum.reject(&Helper.queriable_method?(&1))
|> Enum.filter(&Helper.read_with_wallet_method?(&1))
end

Expand Down

0 comments on commit 354b7e4

Please sign in to comment.