Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add endpoint get fee stats #166

Merged
merged 5 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,63 @@ Soroban.RPC.get_version_info(server)

```

#### Get Fee Stats

Statistics for charged inclusion fees. The inclusion fee statistics are calculated from the inclusion fees that were paid for the transactions to be included onto the ledger.

**Parameters**

- `server`: `Soroban.RPC.Server` struct - The Soroban-RPC server to interact with.

**Example**

```elixir
server = Soroban.RPC.Server.testnet()
Soroban.RPC.get_fee_stats(server)

{:ok,
%Soroban.RPC.GetFeeStatsResponse{
soroban_inclusion_fee: %{
max: "100",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "100",
p70: "100",
p80: "100",
p90: "100",
p95: "100",
p99: "100",
transaction_count: "6",
ledger_count: 50
},
inclusion_fee: %{
max: "200",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "114",
p70: "150",
p80: "150",
p90: "200",
p95: "200",
p99: "200",
transaction_count: "36",
ledger_count: 10
},
latest_ledger: 620373
}}

```

#### Get Events

Clients can request a filtered list of events emitted by a given ledger range.
Expand Down
2 changes: 2 additions & 0 deletions lib/rpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Soroban.RPC do

alias Soroban.RPC.{
GetEvents,
GetFeeStats,
GetHealth,
GetLatestLedger,
GetLedgerEntries,
Expand Down Expand Up @@ -44,6 +45,7 @@ defmodule Soroban.RPC do
defdelegate get_health(server), to: GetHealth, as: :request
defdelegate get_latest_ledger(server), to: GetLatestLedger, as: :request
defdelegate get_network(server), to: GetNetwork, as: :request
defdelegate get_fee_stats(server), to: GetFeeStats, as: :request
defdelegate get_version_info(server), to: GetVersionInfo, as: :request

defp encode_xdr(%LedgerKey{} = ledger_key) do
Expand Down
19 changes: 19 additions & 0 deletions lib/rpc/endpoints/get_fee_stats.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Soroban.RPC.GetFeeStats do
@moduledoc """
GetFeeStats request implementation for Soroban RPC.
"""
@behaviour Soroban.RPC.Endpoint.Spec

alias Soroban.RPC.{GetFeeStatsResponse, Request}

@endpoint "getFeeStats"

@impl true
def request(server, _params \\ nil) do
server
|> Request.new(@endpoint)
|> Request.add_headers([{"Content-Type", "application/json"}])
|> Request.perform()
|> Request.results(as: GetFeeStatsResponse)
end
end
16 changes: 16 additions & 0 deletions lib/rpc/responses/get_fee_stats_response.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Soroban.RPC.GetFeeStatsResponse do
@moduledoc """
`GetFeeStatsResponse` struct definition.
"""

@behaviour Soroban.RPC.Response.Spec

@type soroban_inclusion_fee :: map()
@type inclusion_fee :: map()
@type latest_ledger :: non_neg_integer()

defstruct [:soroban_inclusion_fee, :inclusion_fee, :latest_ledger]

@impl true
def new(attrs), do: struct(%__MODULE__{}, attrs)
end
114 changes: 114 additions & 0 deletions test/rpc/endpoints/get_fee_stats_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
defmodule Soroban.RPC.CannedGetFeeStatsClientImpl do
@moduledoc false
@behaviour Soroban.RPC.Client.Spec

@impl true
def request(_endpoint, _url, _header, _body, _opts) do
send(self(), {:request, "RESPONSE"})

{:ok,
%{
soroban_inclusion_fee: %{
max: "100",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "100",
p70: "100",
p80: "100",
p90: "100",
p95: "100",
p99: "100",
transaction_count: "7",
ledger_count: 50
},
inclusion_fee: %{
max: "200",
min: "100",
mode: "200",
p10: "100",
p20: "100",
p30: "100",
p40: "150",
p50: "200",
p60: "200",
p70: "200",
p80: "200",
p90: "200",
p95: "200",
p99: "200",
transaction_count: "27",
ledger_count: 10
},
latest_ledger: 619_731
}}
end
end

defmodule Soroban.RPC.GetFeeStatsTest do
use ExUnit.Case

alias Soroban.RPC.{
CannedGetFeeStatsClientImpl,
GetFeeStats,
GetFeeStatsResponse,
Server
}

setup do
Application.put_env(:soroban, :http_client_impl, CannedGetFeeStatsClientImpl)

on_exit(fn ->
Application.delete_env(:soroban, :http_client_impl)
end)

%{server: Server.testnet()}
end

test "request/1", %{server: server} do
{:ok,
%GetFeeStatsResponse{
soroban_inclusion_fee: %{
max: "100",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "100",
p70: "100",
p80: "100",
p90: "100",
p95: "100",
p99: "100",
transaction_count: "7",
ledger_count: 50
},
inclusion_fee: %{
max: "200",
min: "100",
mode: "200",
p10: "100",
p20: "100",
p30: "100",
p40: "150",
p50: "200",
p60: "200",
p70: "200",
p80: "200",
p90: "200",
p95: "200",
p99: "200",
transaction_count: "27",
ledger_count: 10
},
latest_ledger: 619_731
}} = GetFeeStats.request(server)
end
end
94 changes: 94 additions & 0 deletions test/rpc/responses/get_fee_stats_response_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
defmodule Soroban.RPC.GetFeeStatsResponseTest do
use ExUnit.Case
alias Soroban.RPC.GetFeeStatsResponse

setup do
%{
result: %{
soroban_inclusion_fee: %{
max: "100",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "100",
p70: "100",
p80: "100",
p90: "100",
p95: "100",
p99: "100",
transaction_count: "7",
ledger_count: 50
},
inclusion_fee: %{
max: "200",
min: "100",
mode: "200",
p10: "100",
p20: "100",
p30: "100",
p40: "150",
p50: "200",
p60: "200",
p70: "200",
p80: "200",
p90: "200",
p95: "200",
p99: "200",
transaction_count: "27",
ledger_count: 10
},
latest_ledger: 619_731
}
}
end

describe "new/1" do
test "when successful transaction", %{
result: result
} do
%GetFeeStatsResponse{
soroban_inclusion_fee: %{
max: "100",
min: "100",
mode: "100",
p10: "100",
p20: "100",
p30: "100",
p40: "100",
p50: "100",
p60: "100",
p70: "100",
p80: "100",
p90: "100",
p95: "100",
p99: "100",
transaction_count: "7",
ledger_count: 50
},
inclusion_fee: %{
max: "200",
min: "100",
mode: "200",
p10: "100",
p20: "100",
p30: "100",
p40: "150",
p50: "200",
p60: "200",
p70: "200",
p80: "200",
p90: "200",
p95: "200",
p99: "200",
transaction_count: "27",
ledger_count: 10
},
latest_ledger: 619_731
} = GetFeeStatsResponse.new(result)
end
end
end
Loading