From 702c57ad13ace5bead7fdd10d61ec66c692f8982 Mon Sep 17 00:00:00 2001 From: akorchyn Date: Thu, 3 Oct 2024 17:19:01 +0300 Subject: [PATCH] feat: basic tracing for sending/signing/executing/quering --- .gitignore | 2 + Cargo.lock | 259 +++++++++++++--------------- Cargo.toml | 6 +- README.md | 2 +- src/common/query.rs | 114 +++++++++--- src/common/send.rs | 115 ++++++++++-- src/signer/access_keyfile_signer.rs | 10 ++ src/signer/keystore.rs | 20 ++- src/signer/ledger.rs | 18 +- src/signer/mod.rs | 17 +- src/signer/secret_key.rs | 9 + 11 files changed, 386 insertions(+), 186 deletions(-) diff --git a/.gitignore b/.gitignore index 300ab6b..ae01339 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ seed_phrase contract_rs.wasm shell.nix +.envrc +.direnv diff --git a/Cargo.lock b/Cargo.lock index 6555c11..5b74c05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arbitrary" @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -91,13 +91,13 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-trait" -version = "0.1.82" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -108,9 +108,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -253,7 +253,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "syn_derive", ] @@ -295,9 +295,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytesize" @@ -340,9 +340,9 @@ dependencies = [ [[package]] name = "cargo-near-build" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "110e4e3b4dc5187c77581a49866018db00c1f4b1b108762aea203e1f35b14445" +checksum = "cd00f13698319e43d9af5b1afc7045131342f3097dd78320a09bb6303bbf2d06" dependencies = [ "bs58 0.5.1", "camino", @@ -352,13 +352,13 @@ dependencies = [ "eyre", "hex", "libloading", - "log", "near-abi", "rustc_version", "schemars", "serde_json", "sha2 0.10.8", "symbolic-debuginfo", + "tracing", "zstd 0.13.2", ] @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.18" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "jobserver", "libc", @@ -557,7 +557,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -581,7 +581,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -592,7 +592,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -647,7 +647,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -660,7 +660,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -792,7 +792,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -862,9 +862,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -981,7 +981,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1074,7 +1074,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.5.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -1089,9 +1089,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -1197,9 +1197,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "hyper" @@ -1256,9 +1256,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -1269,16 +1269,15 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1338,12 +1337,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -1450,9 +1449,9 @@ dependencies = [ [[package]] name = "keyring" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030a9b84bb2a2f3673d4c8b8236091ed5d8f6b66a56d8085471d8abd5f3c6a80" +checksum = "5fa83d1ca02db069b5fbe94b23b584d588e989218310c9c15015bb5571ef1a94" dependencies = [ "byteorder", "dbus-secret-service", @@ -1512,9 +1511,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libdbus-sys" @@ -1670,6 +1669,7 @@ dependencies = [ "slipped10", "thiserror", "tokio", + "tracing", "url", "zstd 0.13.2", ] @@ -1970,7 +1970,7 @@ checksum = "df598b0785a3e36d7e4fb73afcdf20536988b13d07cead71dfa777db4783e552" dependencies = [ "quote", "serde", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1981,7 +1981,7 @@ checksum = "647ef261df99ad877c08c97af2f10368c8b8cde0968250d3482a5a249e9f3926" dependencies = [ "near-rpc-error-core", "serde", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2031,7 +2031,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "strum_macros 0.26.4", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2302,9 +2302,12 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -2335,7 +2338,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2368,9 +2371,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a91171844676f8c7990ce64959210cd2eaef32c2612c50f9fae9f8aaa6065a6" +checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537" dependencies = [ "borsh", "num-traits", @@ -2467,7 +2470,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2484,9 +2487,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plain" @@ -2494,6 +2497,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2625,9 +2634,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -2645,9 +2654,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -2657,9 +2666,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -2668,15 +2677,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", "bytes", @@ -2776,19 +2785,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-webpki" @@ -2843,7 +2851,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2875,7 +2883,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2912,9 +2920,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -2946,7 +2954,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2957,7 +2965,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2980,7 +2988,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2997,15 +3005,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +checksum = "9720086b3357bcb44fce40117d769a4d068c70ecfa190850a980a71755f66fcc" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -3015,14 +3023,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +checksum = "5f1abbfe725f27678f4663bcacb75a83e829fd464c25d78dd038a3a29e307cec" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3031,7 +3039,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -3149,23 +3157,23 @@ dependencies = [ [[package]] name = "snafu" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b835cb902660db3415a672d862905e791e54d306c6e8189168c7f3d9ae1c79d" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" dependencies = [ "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3254,7 +3262,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3318,9 +3326,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -3336,7 +3344,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3377,9 +3385,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" dependencies = [ "filetime", "libc", @@ -3388,9 +3396,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -3401,22 +3409,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3491,7 +3499,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3547,36 +3555,15 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "toml_datetime", "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.3" @@ -3602,7 +3589,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3640,9 +3627,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" @@ -3764,7 +3751,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -3798,7 +3785,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3827,9 +3814,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.5" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -4057,9 +4044,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -4108,7 +4095,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9044d2f..b802be4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ serde_json = "1.0.57" slipped10 = { version = "0.4.6" } url = { version = "2", features = ["serde"] } tokio = { version = "1.0", default-features = false, features = ["time"] } +tracing = "0.1" thiserror = "1" @@ -51,14 +52,15 @@ keyring = { version = "3.2", features = [ "windows-native", "sync-secret-service", "vendored", -] } +], optional = true } near-workspaces = { version = "0.14.0", optional = true } [features] -default = ["ledger"] +default = ["ledger", "keystore"] ledger = ["near-ledger"] +keystore = ["dep:keyring"] workspaces = ["dep:near-workspaces"] [dev-dependencies] diff --git a/README.md b/README.md index 7e03670..bb89e97 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The library is already usable and might be used for rapid prototyping, it lacks - [x] ledger is blocking and it's not good in the async runtime - [ ] secure keychain is not that straightforward to use - [x] storage deposit manager for FT calls -- [ ] logging [tracing](https://github.com/tokio-rs/tracing) +- [x] basic logging with tracing for querying/signing/sending transactions ## Examples The crate provides [examples](./examples/) that contain detailed information on using the library. diff --git a/src/common/query.rs b/src/common/query.rs index 8e6c331..46f59aa 100644 --- a/src/common/query.rs +++ b/src/common/query.rs @@ -14,9 +14,12 @@ use near_primitives::{ }, }; use serde::de::DeserializeOwned; +use tracing::{debug, error, info, instrument, trace, warn}; use crate::{config::NetworkConfig, errors::QueryError, types::Data}; +const QUERY_EXECUTOR_TARGET: &str = "near::query::executor"; + type ResultWithMethod = core::result::Result>; pub trait ResponseHandler @@ -137,27 +140,21 @@ where } } - pub async fn fetch_from_mainnet(self) -> ResultWithMethod { - let network = NetworkConfig::mainnet(); - self.fetch_from(&network).await - } - - pub async fn fetch_from_testnet(self) -> ResultWithMethod { - let network = NetworkConfig::testnet(); - self.fetch_from(&network).await - } - + #[instrument(skip(self, network), fields(request_count = self.requests.len()))] pub async fn fetch_from( self, network: &NetworkConfig, ) -> ResultWithMethod { let json_rpc_client = network.json_rpc_client(); + debug!(target: QUERY_EXECUTOR_TARGET, "Preparing queries"); let requests: Vec<_> = self .requests .into_iter() .map(|request| request.create_query(network, self.reference.clone())) .collect::>()?; + + info!(target: QUERY_EXECUTOR_TARGET, "Sending {} queries", requests.len()); let requests = requests .into_iter() .map(|request| json_rpc_client.call(request)); @@ -167,11 +164,23 @@ where .into_iter() .collect::>()?; if requests.is_empty() { + error!(target: QUERY_EXECUTOR_TARGET, "No responses received"); return Err(QueryError::InternalErrorNoResponse); } + debug!(target: QUERY_EXECUTOR_TARGET, "Processing {} responses", requests.len()); self.handler.process_response(requests) } + + pub async fn fetch_from_mainnet(self) -> ResultWithMethod { + let network = NetworkConfig::mainnet(); + self.fetch_from(&network).await + } + + pub async fn fetch_from_testnet(self) -> ResultWithMethod { + let network = NetworkConfig::testnet(); + self.fetch_from(&network).await + } } pub struct RpcBuilder { @@ -205,28 +214,32 @@ where Self { reference, ..self } } - pub async fn fetch_from_mainnet(self) -> ResultWithMethod { - let network = NetworkConfig::mainnet(); - self.fetch_from(&network).await - } - - pub async fn fetch_from_testnet(self) -> ResultWithMethod { - let network = NetworkConfig::testnet(); - self.fetch_from(&network).await - } - + #[instrument(skip(self, network))] pub async fn fetch_from( self, network: &NetworkConfig, ) -> ResultWithMethod { let json_rpc_client = network.json_rpc_client(); - let query_response = json_rpc_client - .call(self.request.create_query(network, self.reference)?) - .await?; + debug!(target: QUERY_EXECUTOR_TARGET, "Preparing query"); + let query = self.request.create_query(network, self.reference)?; + info!(target: QUERY_EXECUTOR_TARGET, "Sending query"); + let query_response = json_rpc_client.call(query).await?; + + debug!(target: QUERY_EXECUTOR_TARGET, "Processing query response"); self.handler.process_response(vec![query_response]) } + + pub async fn fetch_from_mainnet(self) -> ResultWithMethod { + let network = NetworkConfig::mainnet(); + self.fetch_from(&network).await + } + + pub async fn fetch_from_testnet(self) -> ResultWithMethod { + let network = NetworkConfig::testnet(); + self.fetch_from(&network).await + } } #[derive(Clone, Debug)] @@ -333,7 +346,11 @@ where &self, response: Vec, ) -> ResultWithMethod { - Handler::process_response(&self.handler, response).map(|data| (self.post_process)(data)) + trace!(target: QUERY_EXECUTOR_TARGET, "Processing response with postprocessing, response count: {}", response.len()); + Handler::process_response(&self.handler, response).map(|data| { + trace!(target: QUERY_EXECUTOR_TARGET, "Applying postprocessing"); + (self.post_process)(data) + }) } fn request_amount(&self) -> usize { @@ -364,6 +381,7 @@ where if let near_jsonrpc_primitives::types::query::QueryResponseKind::CallResult(result) = response.kind { + trace!(target: QUERY_EXECUTOR_TARGET, "Deserializing CallResult, result size: {} bytes", result.result.len()); let data: Response = serde_json::from_slice(&result.result)?; Ok(Data { data, @@ -371,6 +389,7 @@ where block_hash: response.block_hash, }) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "CallResult", got: response.kind, @@ -399,12 +418,18 @@ impl ResponseHandler for AccountViewHandler { if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewAccount(account) = response.kind { + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed ViewAccount response: balance: {}, locked: {}", + account.amount, account.locked + ); Ok(Data { data: account, block_height: response.block_height, block_hash: response.block_hash, }) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "ViewAccount", got: response.kind, @@ -429,11 +454,18 @@ impl ResponseHandler for AccessKeyListHandler { .into_iter() .next() .ok_or(QueryError::InternalErrorNoResponse)?; - if let near_jsonrpc_primitives::types::query::QueryResponseKind::AccessKeyList(account) = - response.kind + if let near_jsonrpc_primitives::types::query::QueryResponseKind::AccessKeyList( + access_key_list, + ) = response.kind { - Ok(account) + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed AccessKeyList response, keys count: {}", + access_key_list.keys.len() + ); + Ok(access_key_list) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "AccessKeyList", got: response.kind, @@ -461,12 +493,19 @@ impl ResponseHandler for AccessKeyHandler { if let near_jsonrpc_primitives::types::query::QueryResponseKind::AccessKey(key) = response.kind { + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed AccessKey response, nonce: {}, permission: {:?}", + key.nonce, + key.permission + ); Ok(Data { data: key, block_height: response.block_height, block_hash: response.block_hash, }) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "AccessKey", got: response.kind, @@ -494,12 +533,19 @@ impl ResponseHandler for ViewStateHandler { if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewState(data) = response.kind { + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed ViewState response, values count: {}, proof nodes: {}", + data.values.len(), + data.proof.len() + ); Ok(Data { data, block_height: response.block_height, block_hash: response.block_hash, }) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "ViewState", got: response.kind, @@ -527,12 +573,19 @@ impl ResponseHandler for ViewCodeHandler { if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewCode(code) = response.kind { + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed ViewCode response, code size: {} bytes, hash: {:?}", + code.code.len(), + code.hash + ); Ok(Data { data: code, block_height: response.block_height, block_hash: response.block_hash, }) } else { + warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind); Err(QueryError::UnexpectedResponse { expected: "ViewCode", got: response.kind, @@ -558,6 +611,12 @@ impl ResponseHandler for RpcValidatorHandler { .next() .ok_or(QueryError::InternalErrorNoResponse)?; + info!( + target: QUERY_EXECUTOR_TARGET, + "Processed EpochValidatorInfo response, epoch height: {}, validators count: {}", + response.epoch_height, + response.current_validators.len() + ); Ok(response) } } @@ -571,6 +630,7 @@ impl ResponseHandler for () { &self, _response: Vec, ) -> ResultWithMethod { + trace!(target: QUERY_EXECUTOR_TARGET, "Processed empty response handler"); Ok(()) } } diff --git a/src/common/send.rs b/src/common/send.rs index 51522a4..2f2a964 100644 --- a/src/common/send.rs +++ b/src/common/send.rs @@ -9,6 +9,7 @@ use near_primitives::{ views::FinalExecutionOutcomeView, }; use reqwest::Response; +use tracing::{debug, error, info, warn}; use crate::{ config::NetworkConfig, @@ -24,6 +25,9 @@ use super::{ signed_delegate_action::SignedDelegateActionAsBase64, META_TRANSACTION_VALID_FOR_DEFAULT, }; +const TX_EXECUTOR_TARGET: &str = "near::tx::executor"; +const META_EXECUTOR_TARGET: &str = "near::meta::executor"; + #[async_trait::async_trait] pub trait Transactionable: Send + Sync { fn prepopulated(&self) -> PrepopulateTransaction; @@ -160,26 +164,45 @@ impl ExecuteSignedTransaction { let retries = self.retries; let (signed, transactionable) = match &mut self.tr { - TransactionableOrSigned::Transactionable(tr) => (None, tr), - TransactionableOrSigned::Signed((s, tr)) => (Some(s.clone()), tr), + TransactionableOrSigned::Transactionable(tr) => { + debug!(target: TX_EXECUTOR_TARGET, "Preparing unsigned transaction"); + (None, tr) + } + TransactionableOrSigned::Signed((s, tr)) => { + debug!(target: TX_EXECUTOR_TARGET, "Using pre-signed transaction"); + (Some(s.clone()), tr) + } }; if signed.is_none() { + debug!(target: TX_EXECUTOR_TARGET, "Editing transaction with network config"); transactionable.edit_with_network(network).await?; } else { + debug!(target: TX_EXECUTOR_TARGET, "Validating pre-signed transaction with network config"); transactionable.validate_with_network(network).await?; } let signed = match signed { Some(s) => s, - None => self - .presign_with(network) - .await? - .tr - .signed() - .expect("Expect to have it signed"), + None => { + debug!(target: TX_EXECUTOR_TARGET, "Signing transaction"); + self.presign_with(network) + .await? + .tr + .signed() + .expect("Expect to have it signed") + } }; + info!( + target: TX_EXECUTOR_TARGET, + "Broadcasting signed transaction. Hash: {:?}, Signer: {:?}, Receiver: {:?}, Nonce: {}", + signed.get_hash(), + signed.transaction.signer_id(), + signed.transaction.receiver_id(), + signed.transaction.nonce(), + ); + Self::send_impl(network, signed, retries, sleep_duration).await } @@ -205,6 +228,11 @@ impl ExecuteSignedTransaction { ) -> Result { let mut retries = (1..=retries).rev(); let transaction_info = loop { + debug!( + target: TX_EXECUTOR_TARGET, + "Attempting to broadcast transaction. Retries left: {}", + retries.len() + ); let transaction_info_result = network .json_rpc_client() .call( @@ -215,14 +243,35 @@ impl ExecuteSignedTransaction { .await; match transaction_info_result { Ok(response) => { + info!( + target: TX_EXECUTOR_TARGET, + "Transaction successfully broadcasted. Transaction hash: {:?}", + response.transaction.hash + ); break response; } Err(err) => { if is_critical_error(&err) { + error!( + target: TX_EXECUTOR_TARGET, + "Critical error encountered while broadcasting transaction: {:?}", + err + ); return Err(ExecuteTransactionError::CriticalTransactionError(err)); } else if retries.next().is_some() { + warn!( + target: TX_EXECUTOR_TARGET, + "Error encountered while broadcasting transaction. Retrying in {:?}. Error: {:?}", + sleep_duration, + err + ); tokio::time::sleep(sleep_duration).await; } else { + error!( + target: TX_EXECUTOR_TARGET, + "All retries exhausted. Failed to broadcast transaction: {:?}", + err + ); return Err(ExecuteTransactionError::RetriesExhausted(err)); } } @@ -335,26 +384,45 @@ impl ExecuteMetaTransaction { network: &NetworkConfig, ) -> Result { let (signed, transactionable) = match &mut self.tr { - TransactionableOrSigned::Transactionable(tr) => (None, tr), - TransactionableOrSigned::Signed((s, tr)) => (Some(s.clone()), tr), + TransactionableOrSigned::Transactionable(tr) => { + debug!(target: META_EXECUTOR_TARGET, "Preparing unsigned meta transaction"); + (None, tr) + } + TransactionableOrSigned::Signed((s, tr)) => { + debug!(target: META_EXECUTOR_TARGET, "Using pre-signed meta transaction"); + (Some(s.clone()), tr) + } }; if signed.is_none() { + debug!(target: META_EXECUTOR_TARGET, "Editing meta transaction with network config"); transactionable.edit_with_network(network).await?; } else { + debug!(target: META_EXECUTOR_TARGET, "Validating pre-signed meta transaction with network config"); transactionable.validate_with_network(network).await?; } let signed = match signed { Some(s) => s, - None => self - .presign_with(network) - .await? - .tr - .signed() - .expect("Expect to have it signed"), + None => { + debug!(target: META_EXECUTOR_TARGET, "Signing meta transaction"); + self.presign_with(network) + .await? + .tr + .signed() + .expect("Expect to have it signed") + } }; + info!( + target: META_EXECUTOR_TARGET, + "Broadcasting signed meta transaction. Signer: {:?}, Receiver: {:?}, Nonce: {}, Valid until: {}", + signed.delegate_action.sender_id, + signed.delegate_action.receiver_id, + signed.delegate_action.nonce, + signed.delegate_action.max_block_height + ); + Self::send_impl(network, signed).await } @@ -375,9 +443,14 @@ impl ExecuteMetaTransaction { let client = reqwest::Client::new(); let json_payload = serde_json::json!({ "signed_delegate_action": SignedDelegateActionAsBase64::from( - tr + tr.clone() ).to_string(), }); + debug!( + target: META_EXECUTOR_TARGET, + "Sending meta transaction to relayer. Payload: {:?}", + json_payload + ); let resp = client .post( network @@ -388,6 +461,14 @@ impl ExecuteMetaTransaction { .json(&json_payload) .send() .await?; + + info!( + target: META_EXECUTOR_TARGET, + "Meta transaction sent to relayer. Status: {}, Signer: {:?}, Receiver: {:?}", + resp.status(), + tr.delegate_action.sender_id, + tr.delegate_action.receiver_id + ); Ok(resp) } } diff --git a/src/signer/access_keyfile_signer.rs b/src/signer/access_keyfile_signer.rs index 9539ff4..035f026 100644 --- a/src/signer/access_keyfile_signer.rs +++ b/src/signer/access_keyfile_signer.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use near_crypto::{PublicKey, SecretKey}; use near_primitives::{hash::CryptoHash, transaction::Transaction, types::Nonce}; +use tracing::{debug, instrument, trace}; use super::{AccountKeyPair, SignerTrait}; use crate::{ @@ -9,14 +10,18 @@ use crate::{ types::transactions::PrepopulateTransaction, }; +const ACCESS_KEYFILE_SIGNER_TARGET: &str = "near::signer::access_keyfile"; + #[derive(Debug, Clone)] pub struct AccessKeyFileSigner { keypair: AccountKeyPair, } impl AccessKeyFileSigner { + #[instrument(skip(path), fields(path = %path.display()))] pub fn new(path: PathBuf) -> Result { let keypair = AccountKeyPair::load_access_key_file(&path)?; + debug!(target: ACCESS_KEYFILE_SIGNER_TARGET, "Access key file loaded successfully"); Ok(Self { keypair }) } @@ -24,6 +29,7 @@ impl AccessKeyFileSigner { #[async_trait::async_trait] impl SignerTrait for AccessKeyFileSigner { + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] fn tx_and_secret( &self, tr: PrepopulateTransaction, @@ -31,6 +37,7 @@ impl SignerTrait for AccessKeyFileSigner { nonce: Nonce, block_hash: CryptoHash, ) -> Result<(Transaction, SecretKey), SignerError> { + debug!(target: ACCESS_KEYFILE_SIGNER_TARGET, "Creating transaction"); let mut transaction = Transaction::new_v0( tr.signer_id.clone(), public_key, @@ -40,10 +47,13 @@ impl SignerTrait for AccessKeyFileSigner { ); *transaction.actions_mut() = tr.actions; + trace!(target: ACCESS_KEYFILE_SIGNER_TARGET, "Transaction created, returning with secret key"); Ok((transaction, self.keypair.private_key.to_owned())) } + #[instrument(skip(self))] fn get_public_key(&self) -> Result { + debug!(target: ACCESS_KEYFILE_SIGNER_TARGET, "Retrieving public key"); Ok(self.keypair.public_key.clone()) } } diff --git a/src/signer/keystore.rs b/src/signer/keystore.rs index 2257393..3cda127 100644 --- a/src/signer/keystore.rs +++ b/src/signer/keystore.rs @@ -5,6 +5,7 @@ use near_primitives::{ types::{AccountId, Nonce}, views::AccessKeyPermissionView, }; +use tracing::{debug, info, instrument, trace, warn}; use crate::{ config::NetworkConfig, @@ -14,6 +15,8 @@ use crate::{ use super::{AccountKeyPair, SignerTrait}; +const KEYSTORE_SIGNER_TARGET: &str = "near::signer::keystore"; + #[derive(Debug, Clone)] pub struct KeystoreSigner { potential_pubkeys: Vec, @@ -21,6 +24,7 @@ pub struct KeystoreSigner { #[async_trait::async_trait] impl SignerTrait for KeystoreSigner { + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] fn tx_and_secret( &self, tr: PrepopulateTransaction, @@ -28,16 +32,19 @@ impl SignerTrait for KeystoreSigner { nonce: Nonce, block_hash: CryptoHash, ) -> Result<(Transaction, SecretKey), SignerError> { + debug!(target: KEYSTORE_SIGNER_TARGET, "Searching for matching public key"); self.potential_pubkeys .iter() .find(|key| *key == &public_key) .ok_or(SignerError::PublicKeyIsNotAvailable)?; + info!(target: KEYSTORE_SIGNER_TARGET, "Retrieving secret key"); // TODO: fix this. Well the search is a bit suboptimal, but it's not a big deal for now let secret = Self::get_secret_key(&tr.signer_id, &public_key, "mainnet") .or_else(|_| Self::get_secret_key(&tr.signer_id, &public_key, "testnet")) .map_err(|_| SignerError::SecretKeyIsNotAvailable)?; + debug!(target: KEYSTORE_SIGNER_TARGET, "Creating transaction"); let mut transaction = Transaction::new_v0( tr.signer_id.clone(), public_key, @@ -47,10 +54,13 @@ impl SignerTrait for KeystoreSigner { ); *transaction.actions_mut() = tr.actions; + info!(target: KEYSTORE_SIGNER_TARGET, "Transaction and secret key prepared successfully"); Ok((transaction, secret.private_key)) } + #[instrument(skip(self))] fn get_public_key(&self) -> Result { + debug!(target: KEYSTORE_SIGNER_TARGET, "Retrieving first public key"); self.potential_pubkeys .first() .cloned() @@ -60,21 +70,25 @@ impl SignerTrait for KeystoreSigner { impl KeystoreSigner { pub fn new_with_pubkey(pub_key: PublicKey) -> Self { + debug!(target: KEYSTORE_SIGNER_TARGET, "Creating new KeystoreSigner with public key"); Self { potential_pubkeys: vec![pub_key], } } + #[instrument(skip(network), fields(account_id = %account_id, network_name = %network.network_name))] pub async fn search_for_keys( account_id: AccountId, network: &NetworkConfig, ) -> Result { + info!(target: KEYSTORE_SIGNER_TARGET, "Searching for keys for account"); let account_keys = crate::account::Account(account_id.clone()) .list_keys() .fetch_from(network) .await?; - let potential_pubkeys = account_keys + debug!(target: KEYSTORE_SIGNER_TARGET, "Filtering and collecting potential public keys"); + let potential_pubkeys: Vec = account_keys .keys .into_iter() // TODO: support functional access keys @@ -86,14 +100,17 @@ impl KeystoreSigner { }) .collect(); + info!(target: KEYSTORE_SIGNER_TARGET, "KeystoreSigner created with {} potential public keys", potential_pubkeys.len()); Ok(Self { potential_pubkeys }) } + #[instrument(skip(public_key), fields(account_id = %account_id, network_name = %network_name))] fn get_secret_key( account_id: &AccountId, public_key: &PublicKey, network_name: &str, ) -> Result { + trace!(target: KEYSTORE_SIGNER_TARGET, "Retrieving secret key from keyring"); let service_name = std::borrow::Cow::Owned(format!("near-{}-{}", network_name, account_id.as_str())); @@ -101,6 +118,7 @@ impl KeystoreSigner { keyring::Entry::new(&service_name, &format!("{}:{}", account_id, public_key))? .get_password()?; + debug!(target: KEYSTORE_SIGNER_TARGET, "Deserializing account key pair"); Ok(serde_json::from_str(&password)?) } } diff --git a/src/signer/ledger.rs b/src/signer/ledger.rs index 7abacd8..d7cda8a 100644 --- a/src/signer/ledger.rs +++ b/src/signer/ledger.rs @@ -4,6 +4,7 @@ use near_primitives::{ types::Nonce, }; use slipped10::BIP32Path; +use tracing::{debug, info, instrument, trace, warn}; use crate::{ errors::{LedgerError, MetaSignError, SignerError}, @@ -12,6 +13,8 @@ use crate::{ use super::SignerTrait; +const LEDGER_SIGNER_TARGET: &str = "near::signer::ledger"; + #[derive(Debug, Clone)] pub struct LedgerSigner { hd_path: BIP32Path, @@ -25,6 +28,7 @@ impl LedgerSigner { #[async_trait::async_trait] impl SignerTrait for LedgerSigner { + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] async fn sign( &self, tr: PrepopulateTransaction, @@ -32,6 +36,7 @@ impl SignerTrait for LedgerSigner { nonce: Nonce, block_hash: CryptoHash, ) -> Result { + debug!(target: LEDGER_SIGNER_TARGET, "Preparing unsigned transaction"); let mut unsigned_tx = Transaction::new_v0( tr.signer_id.clone(), public_key, @@ -43,6 +48,7 @@ impl SignerTrait for LedgerSigner { let unsigned_tx_bytes = borsh::to_vec(&unsigned_tx).map_err(LedgerError::from)?; let hd_path = self.hd_path.clone(); + info!(target: LEDGER_SIGNER_TARGET, "Signing transaction with Ledger"); let signature = tokio::task::spawn_blocking(move || { let unsigned_tx_bytes = unsigned_tx_bytes; let signature = near_ledger::sign_transaction(&unsigned_tx_bytes, hd_path) @@ -51,21 +57,23 @@ impl SignerTrait for LedgerSigner { Ok::<_, LedgerError>(signature) }) .await - // JoinError .map_err(LedgerError::from)?; let signature = signature?; + debug!(target: LEDGER_SIGNER_TARGET, "Creating Signature object"); let signature = near_crypto::Signature::from_parts(near_crypto::KeyType::ED25519, &signature) .map_err(LedgerError::from)?; + info!(target: LEDGER_SIGNER_TARGET, "Transaction signed successfully"); Ok(near_primitives::transaction::SignedTransaction::new( signature, unsigned_tx, )) } + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] async fn sign_meta( &self, tr: PrepopulateTransaction, @@ -74,6 +82,7 @@ impl SignerTrait for LedgerSigner { _block_hash: CryptoHash, max_block_height: near_primitives::types::BlockHeight, ) -> Result { + debug!(target: LEDGER_SIGNER_TARGET, "Preparing delegate action"); let actions = tr .actions .into_iter() @@ -94,6 +103,7 @@ impl SignerTrait for LedgerSigner { .map_err(SignerError::from)?; let hd_path = self.hd_path.clone(); + info!(target: LEDGER_SIGNER_TARGET, "Signing delegate action with Ledger"); let signature = tokio::task::spawn_blocking(move || { let delegate_action_bytes = delegate_action_bytes; let signature = @@ -108,11 +118,13 @@ impl SignerTrait for LedgerSigner { let signature = signature.map_err(SignerError::from)?; + debug!(target: LEDGER_SIGNER_TARGET, "Creating Signature object for delegate action"); let signature = near_crypto::Signature::from_parts(near_crypto::KeyType::ED25519, &signature) .map_err(LedgerError::from) .map_err(SignerError::from)?; + info!(target: LEDGER_SIGNER_TARGET, "Delegate action signed successfully"); Ok(SignedDelegateAction { delegate_action, signature, @@ -126,12 +138,16 @@ impl SignerTrait for LedgerSigner { _nonce: Nonce, _block_hash: CryptoHash, ) -> Result<(Transaction, SecretKey), SignerError> { + warn!(target: LEDGER_SIGNER_TARGET, "Attempted to access secret key, which is not available for Ledger signer"); Err(SignerError::SecretKeyIsNotAvailable) } + #[instrument(skip(self))] fn get_public_key(&self) -> Result { let public_key = near_ledger::get_wallet_id(self.hd_path.clone()) .map_err(|_| SignerError::PublicKeyIsNotAvailable)?; + + trace!(target: LEDGER_SIGNER_TARGET, "Public key retrieved successfully"); Ok(near_crypto::PublicKey::ED25519( near_crypto::ED25519PublicKey::from(public_key.to_bytes()), )) diff --git a/src/signer/mod.rs b/src/signer/mod.rs index e111fe9..34bfd21 100644 --- a/src/signer/mod.rs +++ b/src/signer/mod.rs @@ -17,6 +17,7 @@ use near_primitives::{ }; use serde::Deserialize; use slipped10::BIP32Path; +use tracing::{debug, info, instrument, trace, warn}; use crate::{ config::NetworkConfig, @@ -35,6 +36,8 @@ pub mod keystore; pub mod ledger; pub mod secret_key; +const SIGNER_TARGET: &str = "near::signer"; + #[derive(Debug, Deserialize, Clone)] pub struct AccountKeyPair { pub public_key: near_crypto::PublicKey, @@ -95,6 +98,7 @@ pub struct Signer { } impl Signer { + #[instrument(skip(signer))] pub fn new( signer: T, ) -> Result, SignerError> { @@ -109,11 +113,13 @@ impl Signer { })) } + #[instrument(skip(self, signer))] pub async fn add_signer_to_pool( &self, signer: T, ) -> Result<(), SignerError> { let public_key = signer.get_public_key()?; + debug!(target: SIGNER_TARGET, "Adding signer to pool"); self.pool.write().await.insert(public_key, Box::new(signer)); Ok(()) } @@ -121,13 +127,14 @@ impl Signer { /// Fetches the transaction nonce and block hash associated to the access key. Internally /// caches the nonce as to not need to query for it every time, and ending up having to run /// into contention with others. + #[instrument(skip(self, network), fields(account_id = %account_id))] pub async fn fetch_tx_nonce( &self, account_id: AccountId, public_key: PublicKey, network: &NetworkConfig, ) -> Result<(Nonce, CryptoHash, BlockHeight), SignerError> { - // Fetch latest block_hash since the previous one is now invalid for new transactions: + debug!(target: SIGNER_TARGET, "Fetching transaction nonce"); let nonce_data = crate::account::Account(account_id.clone()) .access_key(public_key.clone()) .fetch_from(network) @@ -137,6 +144,7 @@ impl Signer { if let Some(nonce) = nonce_cache.get(&(account_id.clone(), public_key.clone())) { let nonce = nonce.fetch_add(1, Ordering::SeqCst); drop(nonce_cache); + trace!(target: SIGNER_TARGET, "Nonce fetched from cache"); return Ok((nonce + 1, nonce_data.block_hash, nonce_data.block_height)); } else { drop(nonce_cache); @@ -155,6 +163,7 @@ impl Signer { .fetch_max(nonce_data.data.nonce + 1, Ordering::SeqCst) .max(nonce_data.data.nonce + 1); + info!(target: SIGNER_TARGET, "Nonce fetched and cached"); Ok((nonce, nonce_data.block_hash, nonce_data.block_height)) } @@ -212,6 +221,7 @@ impl Signer { SecretKeySigner::new(account.secret_key().to_string().parse().unwrap()) } + #[instrument(skip(self))] pub async fn get_public_key(&self) -> Result { let index = self.current_public_key.fetch_add(1, Ordering::SeqCst); let public_key = { @@ -221,9 +231,11 @@ impl Signer { .ok_or(SignerError::PublicKeyIsNotAvailable)? .clone() }; + debug!(target: SIGNER_TARGET, "Public key retrieved"); Ok(public_key) } + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] pub async fn sign_meta( &self, tr: PrepopulateTransaction, @@ -241,6 +253,7 @@ impl Signer { .await } + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] pub async fn sign( &self, tr: PrepopulateTransaction, @@ -257,6 +270,7 @@ impl Signer { } } +#[instrument(skip(unsigned_transaction, private_key))] pub fn get_signed_delegate_action( unsigned_transaction: Transaction, private_key: SecretKey, @@ -296,6 +310,7 @@ pub fn get_signed_delegate_action( }) } +#[instrument(skip(seed_phrase_hd_path, master_seed_phrase, password))] pub fn get_secret_key_from_seed( seed_phrase_hd_path: BIP32Path, master_seed_phrase: String, diff --git a/src/signer/secret_key.rs b/src/signer/secret_key.rs index c6b9203..78e8447 100644 --- a/src/signer/secret_key.rs +++ b/src/signer/secret_key.rs @@ -1,17 +1,22 @@ use near_crypto::{PublicKey, SecretKey}; use near_primitives::{hash::CryptoHash, transaction::Transaction, types::Nonce}; +use tracing::{debug, instrument, trace}; use crate::{errors::SignerError, types::transactions::PrepopulateTransaction}; use super::SignerTrait; +const SECRET_KEY_SIGNER_TARGET: &str = "near::signer::secret_key"; + #[derive(Debug, Clone)] pub struct SecretKeySigner { secret_key: SecretKey, public_key: PublicKey, } +#[async_trait::async_trait] impl SignerTrait for SecretKeySigner { + #[instrument(skip(self, tr), fields(signer_id = %tr.signer_id, receiver_id = %tr.receiver_id))] fn tx_and_secret( &self, tr: PrepopulateTransaction, @@ -19,6 +24,7 @@ impl SignerTrait for SecretKeySigner { nonce: Nonce, block_hash: CryptoHash, ) -> Result<(Transaction, SecretKey), SignerError> { + debug!(target: SECRET_KEY_SIGNER_TARGET, "Creating transaction"); let mut transaction = Transaction::new_v0( tr.signer_id.clone(), public_key, @@ -27,9 +33,12 @@ impl SignerTrait for SecretKeySigner { block_hash, ); *transaction.actions_mut() = tr.actions; + + trace!(target: SECRET_KEY_SIGNER_TARGET, "Transaction created, returning with secret key"); Ok((transaction, self.secret_key.clone())) } + #[instrument(skip(self))] fn get_public_key(&self) -> Result { Ok(self.public_key.clone()) }