From bdb0c053201be34c11e9ca9e5f403a56b2cfed85 Mon Sep 17 00:00:00 2001 From: Alisina Bahadori Date: Wed, 7 Aug 2024 12:46:59 -0400 Subject: [PATCH 1/2] Fix nil blocks and add backoff --- lib/ethers/utils.ex | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/ethers/utils.ex b/lib/ethers/utils.ex index 4c6d114..25deee1 100644 --- a/lib/ethers/utils.ex +++ b/lib/ethers/utils.ex @@ -344,7 +344,7 @@ defmodule Ethers.Utils do (The hex encoding *must* start with 0x prefix) """ @spec get_block_timestamp(non_neg_integer() | String.t(), Keyword.t()) :: - {:ok, non_neg_integer()} | {:error, :negative_block_number | term()} + {:ok, non_neg_integer()} | {:error, :negative_block_number | :block_not_found | term()} def get_block_timestamp(block_number, opts \\ []) def get_block_timestamp(block_number, opts) when is_integer(block_number) and block_number >= 0, @@ -356,8 +356,15 @@ defmodule Ethers.Utils do def get_block_timestamp("0x" <> _ = block_number, opts) do {rpc_client, rpc_opts} = Ethers.get_rpc_client(opts) - with {:ok, block} <- rpc_client.eth_get_block_by_number(block_number, false, rpc_opts) do - hex_to_integer(Map.fetch!(block, "timestamp")) + case rpc_client.eth_get_block_by_number(block_number, false, rpc_opts) do + {:ok, nil} -> + {:error, :block_not_found} + + {:ok, block} when is_map(block) -> + block |> Map.fetch!("timestamp") |> hex_to_integer() + + {:error, reason} -> + {:error, reason} end end @@ -372,6 +379,8 @@ defmodule Ethers.Utils do - acceptable_drift: Can be set to override the default acceptable_drift of #{@default_acceptable_drift} seconds. This value can be reduced for more accurate results. - sample_size: Can be set to override the default sample_size of #{@default_sample_size} blocks. + - backoff_timeout: An optional backoff in milliseconds that will happen between RPC calls. + (Useful to prevent quote errors) """ @spec date_to_block_number( Date.t() | DateTime.t() | non_neg_integer(), @@ -423,6 +432,7 @@ defmodule Ethers.Utils do end defp find_and_try_next_block_number(datetime, ref_block_number, current_timestamp, opts) do + maybe_backoff(opts) sample_size = opts[:sample_size] || @default_sample_size sample_start_block_number = max(ref_block_number - sample_size, 0) @@ -435,4 +445,10 @@ defmodule Ethers.Utils do date_to_block_number(datetime, new_block_number, opts) end end + + defp maybe_backoff(opts) do + if timeout = Keyword.get(opts, :backoff_timeout) do + Process.sleep(timeout) + end + end end From a8e05923148245c5c3524a4b71df0480df1ba16a Mon Sep 17 00:00:00 2001 From: Alisina Bahadori Date: Wed, 7 Aug 2024 12:50:18 -0400 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb8e0b..c4934ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,14 @@ ## Unreleased +### Bug fixes + +- Handle `{:ok, nil}` from RPC get block by number request + ### Enhancements - Enable raw use of `Ethers.call/2` (usage without function selector) +- Add optional backoff to `Ethers.Utils.date_to_block_number/3` ## v0.5.1 (2024-08-02)