diff --git a/.gitignore b/.gitignore index 5f32e70..dc3bc43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.idea/ target/ -.env \ No newline at end of file +.env diff --git a/Cargo.lock b/Cargo.lock index 53c24f0..d75286d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -161,7 +161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -218,14 +218,13 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.39", ] [[package]] @@ -833,7 +832,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1299,7 +1298,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1423,12 +1422,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1439,7 +1438,7 @@ checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ "cfg-if", "home", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1861,9 +1860,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -2223,9 +2222,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -2263,7 +2262,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2469,9 +2468,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2579,7 +2578,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2720,9 +2719,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libm" @@ -2760,9 +2759,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -2892,13 +2891,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -3076,9 +3076,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -3325,7 +3325,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -3399,9 +3399,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" @@ -4094,7 +4094,7 @@ dependencies = [ "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4203,15 +4203,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.24" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -4317,7 +4317,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4587,7 +4587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -5033,15 +5033,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -5175,28 +5175,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", @@ -5649,9 +5648,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -5897,7 +5896,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -5906,7 +5905,25 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -5915,13 +5932,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5930,42 +5963,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "0.5.19" @@ -5982,7 +6063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] diff --git a/dump.sql b/dump.sql new file mode 100644 index 0000000..5535caf --- /dev/null +++ b/dump.sql @@ -0,0 +1,543 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 16.2 (Debian 16.2-1.pgdg120+2) +-- Dumped by pg_dump version 16.2 (Debian 16.2-1.pgdg120+2) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: rpc_kind; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.rpc_kind AS ENUM ( + 'http', + 'ws' +); + + +ALTER TYPE public.rpc_kind OWNER TO postgres; + +-- +-- Name: transaction_priority; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.transaction_priority AS ENUM ( + 'slowest', + 'slow', + 'regular', + 'fast', + 'fastest' +); + + +ALTER TYPE public.transaction_priority OWNER TO postgres; + +-- +-- Name: tx_status; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.tx_status AS ENUM ( + 'pending', + 'mined', + 'finalized' +); + + +ALTER TYPE public.tx_status OWNER TO postgres; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: _sqlx_migrations; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public._sqlx_migrations ( + version bigint NOT NULL, + description text NOT NULL, + installed_on timestamp with time zone DEFAULT now() NOT NULL, + success boolean NOT NULL, + checksum bytea NOT NULL, + execution_time bigint NOT NULL +); + + +ALTER TABLE public._sqlx_migrations OWNER TO postgres; + +-- +-- Name: api_keys; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.api_keys ( + relayer_id character(36) NOT NULL, + key_hash bytea NOT NULL +); + + +ALTER TABLE public.api_keys OWNER TO postgres; + +-- +-- Name: block_fees; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.block_fees ( + block_number bigint NOT NULL, + chain_id bigint NOT NULL, + gas_price numeric(78,0) NOT NULL, + fee_estimate json NOT NULL +); + + +ALTER TABLE public.block_fees OWNER TO postgres; + +-- +-- Name: block_txs; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.block_txs ( + block_number bigint NOT NULL, + chain_id bigint NOT NULL, + tx_hash bytea NOT NULL +); + + +ALTER TABLE public.block_txs OWNER TO postgres; + +-- +-- Name: blocks; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.blocks ( + block_number bigint NOT NULL, + chain_id bigint NOT NULL, + "timestamp" timestamp with time zone NOT NULL +); + + +ALTER TABLE public.blocks OWNER TO postgres; + +-- +-- Name: networks; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.networks ( + chain_id bigint NOT NULL, + name character varying(255) NOT NULL +); + + +ALTER TABLE public.networks OWNER TO postgres; + +-- +-- Name: relayers; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.relayers ( + id character(36) NOT NULL, + name character varying(255) NOT NULL, + chain_id bigint NOT NULL, + key_id character varying(255) NOT NULL, + address bytea NOT NULL, + nonce bigint DEFAULT 0 NOT NULL, + current_nonce bigint DEFAULT 0 NOT NULL, + max_inflight_txs bigint DEFAULT 5 NOT NULL, + gas_price_limits json DEFAULT '[]'::json NOT NULL, + created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + enabled boolean DEFAULT true NOT NULL, + max_queued_txs bigint DEFAULT 20 NOT NULL, + CONSTRAINT check_max_queued_txs CHECK ((max_queued_txs > max_inflight_txs)) +); + + +ALTER TABLE public.relayers OWNER TO postgres; + +-- +-- Name: rpcs; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.rpcs ( + id bigint NOT NULL, + chain_id bigint NOT NULL, + url character varying(255) NOT NULL, + kind public.rpc_kind NOT NULL +); + + +ALTER TABLE public.rpcs OWNER TO postgres; + +-- +-- Name: rpcs_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.rpcs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.rpcs_id_seq OWNER TO postgres; + +-- +-- Name: rpcs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.rpcs_id_seq OWNED BY public.rpcs.id; + + +-- +-- Name: sent_transactions; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.sent_transactions ( + tx_id character varying(255) NOT NULL, + initial_max_fee_per_gas bytea NOT NULL, + initial_max_priority_fee_per_gas bytea NOT NULL, + created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + first_submitted_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + mined_at timestamp without time zone, + escalation_count bigint DEFAULT 0 NOT NULL, + last_escalation timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + reorg boolean DEFAULT false NOT NULL, + status public.tx_status DEFAULT 'pending'::public.tx_status NOT NULL, + valid_tx_hash bytea NOT NULL +); + + +ALTER TABLE public.sent_transactions OWNER TO postgres; + +-- +-- Name: transactions; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.transactions ( + id character varying(255) NOT NULL, + tx_to bytea NOT NULL, + data bytea NOT NULL, + value bytea NOT NULL, + gas_limit bytea NOT NULL, + nonce bigint NOT NULL, + priority public.transaction_priority NOT NULL, + relayer_id character(36) NOT NULL, + blobs bytea[] +); + + +ALTER TABLE public.transactions OWNER TO postgres; + +-- +-- Name: tx_hashes; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.tx_hashes ( + tx_hash bytea NOT NULL, + tx_id character varying(255) NOT NULL, + created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + max_fee_per_gas bytea NOT NULL, + max_priority_fee_per_gas bytea NOT NULL, + escalated boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public.tx_hashes OWNER TO postgres; + +-- +-- Name: rpcs id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.rpcs ALTER COLUMN id SET DEFAULT nextval('public.rpcs_id_seq'::regclass); + + +-- +-- Data for Name: _sqlx_migrations; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public._sqlx_migrations (version, description, installed_on, success, checksum, execution_time) FROM stdin; +1 init 2024-08-28 10:18:27.238894+00 t \\x905a3f9a30311790acd172c2a191199f718e2cfbaa755171ed44c3030dd60f16d62ddf488a8655b026b6bc8964cc5de6 26217471 +2 relayers table update 2024-08-28 10:18:27.266537+00 t \\xe88abfb929b6bc2e52d0688650ec44504d79688295efd0ad049a1cccf9881d27f95f5e2e1ee08c8194a3771b7a83c086 1253354 +3 relayers tx limits 2024-08-28 10:18:27.268518+00 t \\xf58e22f225284d44e5aa7351075beac0b00c1148d493ee32054c325af93ee372863a2efeaf64430a61398d9619c194da 1547821 +4 transactions binaries 2024-08-28 10:18:27.270833+00 t \\x33bf859efcafa111b325b0ac04e31c486971eecac5f65df889d03f3eaf5b9b4dc87b91227dc8d15ad43a98093f6a2ddb 1150230 +5 network rpc contraints 2024-08-28 10:18:27.272822+00 t \\x97e47c158f132d21eb6ab870d1c7d55c41cc1e8c47708470d7400aee6a85e217689f3fd3cae9517f999f3968501ac86f 2892266 +\. + + +-- +-- Data for Name: api_keys; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.api_keys (relayer_id, key_hash) FROM stdin; +1b908a34-5dc1-4d2d-a146-5eb46e975830 \\x94dea70371e46e0f5ee7764f501665c89f6c06f70e6fc7250dc7d4465bc44c44 +1b908a34-5dc1-4d2d-a146-5eb46e975830 \\x9335eaa650f38e881d339d05d2f99f779f7dfed328a8578d156a6d8bb3caa936 +\. + + +-- +-- Data for Name: block_fees; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.block_fees (block_number, chain_id, gas_price, fee_estimate) FROM stdin; +5 31337 1513459505 {"percentile_fees": ["0x3b9aca00", "0x3b9aca00", "0x3b9aca00", "0x3b9aca00", "0x3b9aca00"], "base_fee_per_gas": "0x1e9ac531"} +10 31337 1263357969 {"percentile_fees": ["0x23c34600", "0x23c34600", "0x23c34600", "0x23c34600", "0x23c34600"], "base_fee_per_gas": "0xfb28611"} +\. + + +-- +-- Data for Name: block_txs; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.block_txs (block_number, chain_id, tx_hash) FROM stdin; +\. + + +-- +-- Data for Name: blocks; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.blocks (block_number, chain_id, "timestamp") FROM stdin; +5 31337 2024-08-28 10:18:38+00 +6 31337 2024-08-28 10:18:44+00 +7 31337 2024-08-28 10:18:50+00 +8 31337 2024-08-28 10:18:56+00 +9 31337 2024-08-28 10:19:02+00 +10 31337 2024-08-28 10:19:08+00 +\. + + +-- +-- Data for Name: networks; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.networks (chain_id, name) FROM stdin; +31337 Anvil +\. + + +-- +-- Data for Name: relayers; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.relayers (id, name, chain_id, key_id, address, nonce, current_nonce, max_inflight_txs, gas_price_limits, created_at, updated_at, enabled, max_queued_txs) FROM stdin; +1b908a34-5dc1-4d2d-a146-5eb46e975830 Anvil 31337 ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \\xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 1 0 5 [] 2024-08-28 10:18:27.329188 2024-08-28 10:18:32.268294 t 20 +\. + + +-- +-- Data for Name: rpcs; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.rpcs (id, chain_id, url, kind) FROM stdin; +1 31337 http://localhost:44757 http +2 31337 ws://localhost:44757 ws +\. + + +-- +-- Data for Name: sent_transactions; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.sent_transactions (tx_id, initial_max_fee_per_gas, initial_max_priority_fee_per_gas, created_at, updated_at, first_submitted_at, mined_at, escalation_count, last_escalation, reorg, status, valid_tx_hash) FROM stdin; +ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 \\x000000000000000000000000000000000000000000000000000000005a358f31 \\x000000000000000000000000000000000000000000000000000000003b9aca00 2024-08-28 10:18:39.634593 2024-08-28 10:18:39.634593 2024-08-28 10:18:39.634593 \N 13 2024-08-28 10:18:39.634593 f pending \\x8a144a909f38bfcdfe942fb1a53ff33c162cba3ce6ccaad9084dc682c541df32 +\. + + +-- +-- Data for Name: transactions; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.transactions (id, tx_to, data, value, gas_limit, nonce, priority, relayer_id, blobs) FROM stdin; +ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 \\x0000000000000000000000000000000000000000 \\xa9cc4718 \\x0000000000000000000000000000000000000000000000000000000000000000 \\x0000000000000000000000000000000000000000000000000000000000005208 0 regular 1b908a34-5dc1-4d2d-a146-5eb46e975830 \N +\. + + +-- +-- Data for Name: tx_hashes; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.tx_hashes (tx_hash, tx_id, created_at, max_fee_per_gas, max_priority_fee_per_gas, escalated) FROM stdin; +\\x90e88792e7b596ebe9a10ffc3e79c58c47e3e16ca0b35892200bcfaafe00b137 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:39.634593 \\x000000000000000000000000000000000000000000000000000000005a358f31 \\x000000000000000000000000000000000000000000000000000000003b9aca00 t +\\x155cb2def125e4a2a4f335809d37af65a2626b6719d25f9b44a73e9478e66486 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:43.573041 \\x00000000000000000000000000000000000000000000000000000000720d1331 \\x00000000000000000000000000000000000000000000000000000000720d1331 t +\\xf60dd9a450671caf431156753f68ef01c32375325c07c47215f96c8058bba946 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:45.661081 \\x000000000000000000000000000000000000000000000000000000007df8d531 \\x000000000000000000000000000000000000000000000000000000007df8d531 t +\\xb51d95402c44b71662d7d1f099ef12276c6ee49697c349538cbf9f8d1a67cb26 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:47.753635 \\x0000000000000000000000000000000000000000000000000000000089e49731 \\x0000000000000000000000000000000000000000000000000000000089e49731 t +\\x7f6db58aefc43484af56d4a30553ef7e45bfa03367fa5921b92a64166d103891 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:49.819882 \\x0000000000000000000000000000000000000000000000000000000095d05931 \\x0000000000000000000000000000000000000000000000000000000095d05931 t +\\xde7a64fc02a5bd6c12e7ebb0a36ae2b28e47569acd12960dbebefba1c4465c0d ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:51.887904 \\x00000000000000000000000000000000000000000000000000000000a1bc1b31 \\x00000000000000000000000000000000000000000000000000000000a1bc1b31 t +\\x65e9495cb543c0bbc88823822bcf264657b2fb0edb7f716485013479ba19d4f6 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:53.954442 \\x00000000000000000000000000000000000000000000000000000000ada7dd31 \\x00000000000000000000000000000000000000000000000000000000ada7dd31 t +\\xd1489038a15be6c7377afc32ed2e8606acd1f734c60415775425c4696d4b2922 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:19:06.405662 \\x00000000000000000000000000000000000000000000000000000000f52e6931 \\x00000000000000000000000000000000000000000000000000000000f52e6931 t +\\x8a144a909f38bfcdfe942fb1a53ff33c162cba3ce6ccaad9084dc682c541df32 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:19:08.492346 \\x00000000000000000000000000000000000000000000000000000001011a2b31 \\x00000000000000000000000000000000000000000000000000000001011a2b31 f +\\x518c9dd076e2bd8caa4aa5ce2d8be467ff50de9d174da06db7d4663dd259f853 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:56.016698 \\x00000000000000000000000000000000000000000000000000000000b9939f31 \\x00000000000000000000000000000000000000000000000000000000b9939f31 t +\\xfa799adab876e6fa6eefe5b7e2bdc715a7ec3219bf12b58f2138dee5c724e1c7 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:18:58.100538 \\x00000000000000000000000000000000000000000000000000000000c57f6131 \\x00000000000000000000000000000000000000000000000000000000c57f6131 t +\\xd38024302797398d5bf39625e8d283b54639dad2816fff82c292c53467947204 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:19:00.169953 \\x00000000000000000000000000000000000000000000000000000000d16b2331 \\x00000000000000000000000000000000000000000000000000000000d16b2331 t +\\xcdf3eede5ec23b4bfda138e26257f7ca9ade72ed5a1b5c9fd3f0d9dbda26d95e ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:19:02.259047 \\x00000000000000000000000000000000000000000000000000000000dd56e531 \\x00000000000000000000000000000000000000000000000000000000dd56e531 t +\\x29d3df75a7ebf44570f138d0aa86fa77b888ca58a515e67c1e39507c3502d761 ac8f6ebd-2fba-4d43-b9bf-03440e4dc1c2 2024-08-28 10:19:04.348537 \\x00000000000000000000000000000000000000000000000000000000e942a731 \\x00000000000000000000000000000000000000000000000000000000e942a731 t +\. + + +-- +-- Name: rpcs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public.rpcs_id_seq', 2, true); + + +-- +-- Name: _sqlx_migrations _sqlx_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public._sqlx_migrations + ADD CONSTRAINT _sqlx_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: block_fees block_fees_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.block_fees + ADD CONSTRAINT block_fees_pkey PRIMARY KEY (block_number, chain_id); + + +-- +-- Name: blocks blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.blocks + ADD CONSTRAINT blocks_pkey PRIMARY KEY (block_number, chain_id); + + +-- +-- Name: networks networks_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.networks + ADD CONSTRAINT networks_pkey PRIMARY KEY (chain_id); + + +-- +-- Name: relayers relayers_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.relayers + ADD CONSTRAINT relayers_pkey PRIMARY KEY (id); + + +-- +-- Name: rpcs rpcs_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.rpcs + ADD CONSTRAINT rpcs_pkey PRIMARY KEY (id); + + +-- +-- Name: sent_transactions sent_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sent_transactions + ADD CONSTRAINT sent_transactions_pkey PRIMARY KEY (tx_id); + + +-- +-- Name: transactions transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.transactions + ADD CONSTRAINT transactions_pkey PRIMARY KEY (id); + + +-- +-- Name: tx_hashes tx_hashes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.tx_hashes + ADD CONSTRAINT tx_hashes_pkey PRIMARY KEY (tx_hash); + + +-- +-- Name: rpcs unique_chain_id_kind; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.rpcs + ADD CONSTRAINT unique_chain_id_kind UNIQUE (chain_id, kind); + + +-- +-- Name: api_keys api_keys_relayer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.api_keys + ADD CONSTRAINT api_keys_relayer_id_fkey FOREIGN KEY (relayer_id) REFERENCES public.relayers(id) ON DELETE CASCADE; + + +-- +-- Name: block_fees block_fees_block_number_chain_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.block_fees + ADD CONSTRAINT block_fees_block_number_chain_id_fkey FOREIGN KEY (block_number, chain_id) REFERENCES public.blocks(block_number, chain_id) ON DELETE CASCADE; + + +-- +-- Name: block_txs block_txs_block_number_chain_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.block_txs + ADD CONSTRAINT block_txs_block_number_chain_id_fkey FOREIGN KEY (block_number, chain_id) REFERENCES public.blocks(block_number, chain_id) ON DELETE CASCADE; + + +-- +-- Name: rpcs rpcs_chain_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.rpcs + ADD CONSTRAINT rpcs_chain_id_fkey FOREIGN KEY (chain_id) REFERENCES public.networks(chain_id); + + +-- +-- Name: sent_transactions sent_transactions_tx_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sent_transactions + ADD CONSTRAINT sent_transactions_tx_id_fkey FOREIGN KEY (tx_id) REFERENCES public.transactions(id) ON DELETE CASCADE; + + +-- +-- Name: sent_transactions sent_transactions_valid_tx_hash_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sent_transactions + ADD CONSTRAINT sent_transactions_valid_tx_hash_fkey FOREIGN KEY (valid_tx_hash) REFERENCES public.tx_hashes(tx_hash); + + +-- +-- Name: transactions transactions_relayer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.transactions + ADD CONSTRAINT transactions_relayer_id_fkey FOREIGN KEY (relayer_id) REFERENCES public.relayers(id); + + +-- +-- Name: tx_hashes tx_hashes_tx_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.tx_hashes + ADD CONSTRAINT tx_hashes_tx_id_fkey FOREIGN KEY (tx_id) REFERENCES public.transactions(id) ON DELETE CASCADE; + + +-- +-- PostgreSQL database dump complete +-- + diff --git a/src/db.rs b/src/db.rs index 44fcf39..3c85465 100644 --- a/src/db.rs +++ b/src/db.rs @@ -15,6 +15,7 @@ use crate::types::wrappers::h256::H256Wrapper; use crate::types::{ NetworkInfo, RelayerInfo, RelayerUpdate, TransactionPriority, TxStatus, }; +use crate::types::wrappers::hex_u256::HexU256; pub mod data; @@ -271,6 +272,28 @@ impl Database { Ok(tx_count as usize) } + #[instrument(skip(self), level = "debug")] + pub async fn get_relayer_pending_txs_gas_limit_sum( + &self, + relayer_id: &str, + ) -> eyre::Result { + let gas_limits: Vec<(HexU256,)> = sqlx::query_as( + r#" + SELECT t.gas_limit + FROM transactions t + LEFT JOIN sent_transactions s ON (t.id = s.tx_id) + WHERE t.relayer_id = $1 + AND (s.tx_id IS NULL OR s.status = $2) + "#, + ) + .bind(relayer_id) + .bind(TxStatus::Pending) + .fetch_all(&self.pool) + .await?; + + Ok(gas_limits.into_iter().fold(U256::zero(), |acc, (v,)| acc + v.0)) + } + #[instrument(skip(self), level = "debug")] pub async fn create_transaction( &self, diff --git a/src/server.rs b/src/server.rs index de72445..88b86cc 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,6 +1,7 @@ use std::net::SocketAddr; use std::sync::Arc; - +use ethers::middleware::Middleware; +use ethers::providers::{Http, Provider}; use ethers::signers::Signer; use eyre::ContextCompat; use poem::http::StatusCode; @@ -251,6 +252,31 @@ impl RelayerApi { )); } + let relayer_queued_tx_gas_limit_sum = app + .db + .get_relayer_pending_txs_gas_limit_sum(api_token.relayer_id()) + .await?; + + let block_fees = app.db.get_latest_block_fees_by_chain_id(relayer.chain_id).await?; + if let Some(block_fees) = block_fees { + let gas_limit = relayer_queued_tx_gas_limit_sum + req.gas_limit.0; + let estimated_transactions_cost = block_fees.gas_price * gas_limit; + + // TODO: Cache? + let http_provider: Provider = app.http_provider(relayer.chain_id).await?; + + let balance = http_provider.get_balance(relayer.address.0, None).await.map_err(|err| { + eyre::eyre!("Error checking balance: {}", err) + })?; + + if balance < estimated_transactions_cost { + return Err(poem::error::Error::from_string( + "Relayer funds are insufficient for transaction to be mined.".to_string(), + StatusCode::UNPROCESSABLE_ENTITY, + )); + } + } + let res = app .db .create_transaction( diff --git a/src/service.rs b/src/service.rs index 2a510d4..5ca7a67 100644 --- a/src/service.rs +++ b/src/service.rs @@ -82,6 +82,14 @@ impl Service { Ok(()) } + + pub async fn is_estimates_ready_for_chain(&self, chain_id: u64) -> bool { + let res = self._app.db.get_latest_block_fees_by_chain_id(chain_id).await; + match res { + Ok(res) => res.is_some(), + Err(_) => false, + } + } } async fn initialize_predefined_values( diff --git a/src/tasks/index.rs b/src/tasks/index.rs index bdf79c0..5a4194a 100644 --- a/src/tasks/index.rs +++ b/src/tasks/index.rs @@ -108,15 +108,15 @@ pub async fn backfill_to_block( rpc: &Provider, latest_block: Block, ) -> eyre::Result<()> { - // Get the latest block from the db - let Some(latest_db_block_number) = - app.db.get_latest_block_number(chain_id).await? - else { - tracing::info!(chain_id, "No latest block"); - return Ok(()); - }; - - let next_block_number: u64 = latest_db_block_number + 1; + let next_block_number: u64 = + if let Some(latest_db_block_number) = + app.db.get_latest_block_number(chain_id).await? { + latest_db_block_number + 1 + } + else { + tracing::info!(chain_id, "No latest block"); + 0 + }; // Get the first block from the stream and backfill any missing blocks let latest_block_number = latest_block diff --git a/tests/common/anvil_builder.rs b/tests/common/anvil_builder.rs index ac1fd55..0caf782 100644 --- a/tests/common/anvil_builder.rs +++ b/tests/common/anvil_builder.rs @@ -50,7 +50,7 @@ impl AnvilBuilder { tokio::time::sleep(Duration::from_secs(block_time)).await; // We need to seed some transactions so we can get fee estimates on the first block - middleware + let tx = middleware .send_transaction( Eip1559TransactionRequest { to: Some(DEFAULT_ANVIL_ACCOUNT.into()), diff --git a/tests/common/service_builder.rs b/tests/common/service_builder.rs index 9b21d9a..78d89b3 100644 --- a/tests/common/service_builder.rs +++ b/tests/common/service_builder.rs @@ -2,6 +2,7 @@ use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::time::Duration; use ethers::utils::AnvilInstance; +use sqlx::Pool; use tx_sitter::api_key::ApiKey; use tx_sitter::client::TxSitterClient; use tx_sitter::config::{ @@ -94,6 +95,19 @@ impl ServiceBuilder { let client = TxSitterClient::new(format!("http://{}", service.local_addr())); + // Awaits for estimates to be ready + let mut is_estimates_ready = false; + for _ in 0..30 { + if service.is_estimates_ready_for_chain(DEFAULT_ANVIL_CHAIN_ID).await { + is_estimates_ready = true; + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; + } + if !is_estimates_ready { + eyre::bail!("Estimates were not ready!"); + } + Ok((service, client)) } } diff --git a/tests/escalation.rs b/tests/escalation.rs index ceeeb65..407a6ae 100644 --- a/tests/escalation.rs +++ b/tests/escalation.rs @@ -3,7 +3,7 @@ mod common; use crate::common::prelude::*; const ESCALATION_INTERVAL: Duration = Duration::from_secs(2); -const ANVIL_BLOCK_TIME: u64 = 6; +const ANVIL_BLOCK_TIME: u64 = 10; #[tokio::test] async fn escalation() -> eyre::Result<()> { diff --git a/tests/send_too_many_txs.rs b/tests/send_too_many_txs.rs index 1f2a35d..a50ebe0 100644 --- a/tests/send_too_many_txs.rs +++ b/tests/send_too_many_txs.rs @@ -29,6 +29,29 @@ async fn send_too_many_txs() -> eyre::Result<()> { }) .await?; + let provider = setup_provider(anvil.endpoint()).await?; + let init_value: U256 = parse_units("1", "ether")?.into(); + + // Send some funds to created relayer + client + .send_tx( + &api_key, + &SendTxRequest { + to: secondary_relayer_address.clone(), + value: init_value.into(), + data: None, + gas_limit: U256::from(21_000).into(), + priority: TransactionPriority::Regular, + tx_id: None, + blobs: None, + }, + ) + .await?; + + tracing::info!("Waiting for secondary relayer initial balance"); + await_balance(&provider, init_value, secondary_relayer_address.0) + .await?; + let CreateApiKeyResponse { api_key: secondary_api_key, } = client.create_relayer_api_key(&secondary_relayer_id).await?; @@ -42,8 +65,6 @@ async fn send_too_many_txs() -> eyre::Result<()> { ) .await?; - let provider = setup_provider(anvil.endpoint()).await?; - // Send a transaction let value: U256 = parse_units("0.01", "ether")?.into(); diff --git a/tests/send_when_insufficient_funds.rs b/tests/send_when_insufficient_funds.rs new file mode 100644 index 0000000..a187a86 --- /dev/null +++ b/tests/send_when_insufficient_funds.rs @@ -0,0 +1,55 @@ +mod common; + +use tx_sitter::client::ClientError; +use crate::common::prelude::*; + +const ESCALATION_INTERVAL: Duration = Duration::from_secs(2); +const ANVIL_BLOCK_TIME: u64 = 6; + +#[tokio::test] +async fn send_when_insufficient_funds() -> eyre::Result<()> { + setup_tracing(); + + let (db_url, _db_container) = setup_db().await?; + let anvil = AnvilBuilder::default() + .block_time(ANVIL_BLOCK_TIME) + .spawn() + .await?; + + let (_service, client) = ServiceBuilder::default() + .escalation_interval(ESCALATION_INTERVAL) + .build(&anvil, &db_url) + .await?; + + let CreateApiKeyResponse { api_key } = + client.create_relayer_api_key(DEFAULT_RELAYER_ID).await?; + + // Send a transaction + let value: U256 = parse_units("1", "ether")?.into(); + for _ in 0..10 { + let tx = client.send_tx(&api_key, + &SendTxRequest { + to: ARBITRARY_ADDRESS.into(), + value: value.into(), + gas_limit: U256::from_dec_str("1000000000000")?.into(), + ..Default::default() + }, + ).await; + + match tx { + Err(err) => { + match err { + ClientError::TxSitter(status_code, message) => { + assert_eq!(status_code, reqwest::StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!(message, "Relayer funds are insufficient for transaction to be mined."); + return Ok(()); + } + _ => {} + } + } + _ => {} + } + } + + eyre::bail!("Should return error response with information about insufficient funds.") +} \ No newline at end of file