diff --git a/.gitignore b/.gitignore index 78d8a7c..a662463 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ grin.log wallet.seed test_output .idea/ +*.vs +.gitattributes diff --git a/.hooks/pre-commit b/.hooks/pre-commit old mode 100755 new mode 100644 diff --git a/Cargo.lock b/Cargo.lock index 960d04c..9f3c588 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,28 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite 0.2.15", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", +] + [[package]] name = "atty" version = "0.2.14" @@ -202,12 +224,6 @@ dependencies = [ "safemem", ] -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "base64" version = "0.12.3" @@ -220,6 +236,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64ct" version = "1.6.0" @@ -339,9 +361,9 @@ checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "built" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" +checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" dependencies = [ "git2", ] @@ -388,10 +410,11 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" -version = "1.1.31" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -498,32 +521,16 @@ dependencies = [ "futures 0.3.31", ] -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - [[package]] name = "core-foundation" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "core-foundation-sys 0.8.7", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -633,15 +640,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ct-logs" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" -dependencies = [ - "sct", -] - [[package]] name = "ctor" version = "0.1.26" @@ -976,6 +974,12 @@ dependencies = [ "toml", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "flate2" version = "1.0.34" @@ -1053,9 +1057,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -1232,9 +1236,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" -version = "0.19.0" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" dependencies = [ "bitflags 2.6.0", "libc", @@ -1245,11 +1249,12 @@ dependencies = [ [[package]] name = "grin_api" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6443239e75a15c517ce24fe4dd3ef257898ae0224e6b7c993db28794e13ecf3e" +checksum = "f6f8d4159c8b006a921c0e98b34f1419c175127ee48519b8b1ad00b2036d5011" dependencies = [ - "bytes 0.5.6", + "async-stream", + "bytes 1.8.0", "easy-jsonrpc-mw", "futures 0.3.31", "grin_chain", @@ -1259,28 +1264,29 @@ dependencies = [ "grin_store", "grin_util", "http", - "hyper", - "hyper-rustls 0.20.0", + "hyper 0.14.32", + "hyper-rustls 0.23.2", "hyper-timeout", "lazy_static", "log", "regex", - "ring", - "rustls 0.17.0", + "ring 0.16.20", + "rustls 0.20.9", + "rustls-pemfile", "serde", "serde_derive", "serde_json", "thiserror", - "tokio", - "tokio-rustls 0.13.1", + "tokio 1.42.1", + "tokio-rustls 0.23.4", "url", ] [[package]] name = "grin_chain" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdedcee9e20e0cc8dc1460b37b3951306c774a6aa5788e3f45addc56e60f7fbe" +checksum = "1ae4110494f8864a7acaa95a6565cea73a769203353d33afa2491a0303ef5e96" dependencies = [ "bit-vec", "bitflags 1.3.2", @@ -1302,9 +1308,9 @@ dependencies = [ [[package]] name = "grin_core" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fbf242a2a23a6554dd4c430574d2563993cf5f44921f953635e8a177cf2506" +checksum = "e9f7959afef3976c8530f39416364dd8e47c24b20774a8c5432645fc70aeba67" dependencies = [ "blake2-rfc", "byteorder", @@ -1329,9 +1335,9 @@ dependencies = [ [[package]] name = "grin_keychain" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abeb1c22f48269a0bf463de589f8961d8bbb554def5e5e405710ead9a1b4c71a" +checksum = "4da89816a601ca89d9718aa3fac1ae933086d36790fb3b9d85a57b64ba20173f" dependencies = [ "blake2-rfc", "byteorder", @@ -1352,9 +1358,9 @@ dependencies = [ [[package]] name = "grin_p2p" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b0ecc5597244d698ec4e1ea2e7d04c3b209f496db16731a04f06af41572c54" +checksum = "6d8ee1812124b8843de27626c5e65f43eae7ca855eeb6060286c6b3f31880548" dependencies = [ "bitflags 1.3.2", "bytes 0.5.6", @@ -1375,9 +1381,9 @@ dependencies = [ [[package]] name = "grin_pool" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b758b202f034a03b894e732c716ddece8994fae5d8da1e074b1a9e07219f2b" +checksum = "ddce3861a8af1036d36746eeb80d5efc805587ab7dbc19d7bef13c127d567cc8" dependencies = [ "blake2-rfc", "chrono", @@ -1393,9 +1399,9 @@ dependencies = [ [[package]] name = "grin_secp256k1zkp" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06832645c3d28079245827908045946db48e5d62b4c54b40701c7e21327e2571" +checksum = "bf7bb95f155b1eede2648a1b9afbba82bc3d9f2af0518b478767559a572bd973" dependencies = [ "arrayvec 0.7.6", "cc", @@ -1408,9 +1414,9 @@ dependencies = [ [[package]] name = "grin_store" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708e53758263fa17dfd3fc46419ded59a84d07818e1ee7526b0d47ba268f1362" +checksum = "6a6d8762c27886d4dbeeae187e761bafef84e099096f0da4987d96dba7192e33" dependencies = [ "byteorder", "croaring", @@ -1428,9 +1434,9 @@ dependencies = [ [[package]] name = "grin_util" -version = "5.3.3" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1433d76d0e95c2ed20e1008e9891adfae64812d1bdc5ec71ed5499dcaca2986" +checksum = "c8ecf6160820c449a0d5a2f856cd8d9b0bacf1fff4a09785cf2b6762d9475a6a" dependencies = [ "anyhow", "backtrace", @@ -1498,7 +1504,7 @@ dependencies = [ "grin_wallet_util", "log", "rand 0.6.5", - "ring", + "ring 0.16.20", "serde", "serde_derive", "serde_json", @@ -1539,20 +1545,20 @@ dependencies = [ "grin_wallet_impls", "grin_wallet_libwallet", "grin_wallet_util", - "hyper", + "hyper 0.14.32", "lazy_static", "log", "prettytable-rs", "qr_code", "rand 0.7.3", "remove_dir_all", - "ring", + "ring 0.16.20", "serde", "serde_derive", "serde_json", "term 0.6.1", "thiserror", - "tokio", + "tokio 0.2.25", "url", "uuid", ] @@ -1583,14 +1589,14 @@ dependencies = [ "regex", "remove_dir_all", "reqwest", - "ring", + "ring 0.16.20", "serde", "serde_derive", "serde_json", "sysinfo", "thiserror", "timer", - "tokio", + "tokio 0.2.25", "url", "uuid", "x25519-dalek 0.6.0", @@ -1664,12 +1670,31 @@ dependencies = [ "http", "indexmap 1.9.3", "slab", - "tokio", - "tokio-util", + "tokio 0.2.25", + "tokio-util 0.3.1", "tracing", "tracing-futures", ] +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes 1.8.0", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.6.0", + "slab", + "tokio 1.42.1", + "tokio-util 0.7.17", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1768,6 +1793,17 @@ dependencies = [ "http", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes 1.8.0", + "http", + "pin-project-lite 0.2.15", +] + [[package]] name = "httparse" version = "1.9.5" @@ -1780,6 +1816,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" @@ -1796,36 +1838,42 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.2.7", "http", - "http-body", + "http-body 0.3.1", "httparse", - "httpdate", + "httpdate 0.3.2", "itoa 0.4.8", "pin-project", - "socket2", - "tokio", + "socket2 0.3.19", + "tokio 0.2.25", "tower-service", "tracing", "want", ] [[package]] -name = "hyper-rustls" -version = "0.20.0" +name = "hyper" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ - "bytes 0.5.6", - "ct-logs", + "bytes 1.8.0", + "futures-channel", + "futures-core", "futures-util", - "hyper", - "log", - "rustls 0.17.0", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.13.1", - "webpki", + "h2 0.3.27", + "http", + "http-body 0.4.6", + "httparse", + "httpdate 1.0.3", + "itoa 1.0.11", + "pin-project-lite 0.2.15", + "socket2 0.5.8", + "tokio 1.42.1", + "tower-service", + "tracing", + "want", ] [[package]] @@ -1836,23 +1884,38 @@ checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6" dependencies = [ "bytes 0.5.6", "futures-util", - "hyper", + "hyper 0.13.10", "log", "rustls 0.18.1", - "tokio", + "tokio 0.2.25", "tokio-rustls 0.14.1", - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper 0.14.32", + "log", + "rustls 0.20.9", + "rustls-native-certs", + "tokio 1.42.1", + "tokio-rustls 0.23.4", ] [[package]] name = "hyper-timeout" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d1f9b0b8258e3ef8f45928021d3ef14096c2b93b99e4b8cfcabf1f58ec84b0a" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "bytes 0.5.6", - "hyper", - "tokio", + "hyper 0.14.32", + "pin-project-lite 0.2.15", + "tokio 1.42.1", "tokio-io-timeout", ] @@ -1863,9 +1926,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" dependencies = [ "bytes 0.5.6", - "hyper", + "hyper 0.13.10", "native-tls", - "tokio", + "tokio 0.2.25", "tokio-tls", ] @@ -1945,7 +2008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", - "core-foundation-sys 0.8.7", + "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", @@ -1961,6 +2024,87 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr 0.8.2", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1969,12 +2113,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -2118,9 +2273,9 @@ checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libgit2-sys" -version = "0.17.0+1.8.1" +version = "0.18.3+1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" dependencies = [ "cc", "libc", @@ -2183,6 +2338,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "lmdb-zero" version = "0.4.4" @@ -2333,6 +2494,17 @@ dependencies = [ "winapi 0.2.8", ] +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + [[package]] name = "mio-named-pipes" version = "0.1.7" @@ -2340,7 +2512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", - "mio", + "mio 0.6.23", "miow 0.3.7", "winapi 0.3.9", ] @@ -2353,7 +2525,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", - "mio", + "mio 0.6.23", ] [[package]] @@ -2405,8 +2577,8 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 2.11.1", - "security-framework-sys 2.12.0", + "security-framework", + "security-framework-sys", "tempfile", ] @@ -2735,9 +2907,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" @@ -2832,6 +3004,15 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -3243,8 +3424,8 @@ dependencies = [ "futures-core", "futures-util", "http", - "http-body", - "hyper", + "http-body 0.3.1", + "hyper 0.13.10", "hyper-rustls 0.21.0", "hyper-tls", "ipnet", @@ -3259,7 +3440,7 @@ dependencies = [ "rustls 0.18.1", "serde", "serde_urlencoded", - "tokio", + "tokio 0.2.25", "tokio-rustls 0.14.1", "tokio-socks", "tokio-tls", @@ -3281,11 +3462,25 @@ dependencies = [ "libc", "once_cell", "spin", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi 0.3.9", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.15", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -3378,19 +3573,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" -dependencies = [ - "base64 0.11.0", - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.18.1" @@ -3399,21 +3581,42 @@ checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" dependencies = [ "base64 0.12.3", "log", - "ring", - "sct", - "webpki", + "ring 0.16.20", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct 0.7.1", + "webpki 0.22.4", ] [[package]] name = "rustls-native-certs" -version = "0.3.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls 0.17.0", + "rustls-pemfile", "schannel", - "security-framework 0.4.4", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", ] [[package]] @@ -3504,8 +3707,18 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", ] [[package]] @@ -3526,19 +3739,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "security-framework" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.7.0", - "core-foundation-sys 0.7.0", - "libc", - "security-framework-sys 0.4.3", -] - [[package]] name = "security-framework" version = "2.11.1" @@ -3546,20 +3746,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation 0.9.4", - "core-foundation-sys 0.8.7", - "libc", - "security-framework-sys 2.12.0", -] - -[[package]] -name = "security-framework-sys" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" -dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation", + "core-foundation-sys", "libc", + "security-framework-sys", ] [[package]] @@ -3568,7 +3758,7 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ - "core-foundation-sys 0.8.7", + "core-foundation-sys", "libc", ] @@ -3791,12 +3981,28 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "strsim" version = "0.8.0" @@ -3872,6 +4078,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", +] + [[package]] name = "sysinfo" version = "0.29.11" @@ -3879,7 +4096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" dependencies = [ "cfg-if 1.0.0", - "core-foundation-sys 0.8.7", + "core-foundation-sys", "libc", "ntapi", "once_cell", @@ -3991,6 +4208,16 @@ dependencies = [ "displaydoc", ] +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -4019,25 +4246,43 @@ dependencies = [ "lazy_static", "libc", "memchr", - "mio", + "mio 0.6.23", "mio-named-pipes", "mio-uds", "num_cpus", "pin-project-lite 0.1.12", "signal-hook-registry", "slab", - "tokio-macros", + "tokio-macros 0.2.6", "winapi 0.3.9", ] [[package]] -name = "tokio-io-timeout" -version = "0.4.0" +name = "tokio" +version = "1.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9390a43272c8a6ac912ed1d1e2b6abeafd5047e05530a2fa304deee041a06215" +checksum = "2209a14885b74764cce87ffa777ffa1b8ce81a3f3166c6f886b83337fe7e077f" dependencies = [ - "bytes 0.5.6", - "tokio", + "backtrace", + "bytes 1.8.0", + "libc", + "mio 1.1.0", + "parking_lot 0.12.3", + "pin-project-lite 0.2.15", + "signal-hook-registry", + "socket2 0.5.8", + "tokio-macros 2.4.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" +dependencies = [ + "pin-project-lite 0.2.15", + "tokio 1.42.1", ] [[package]] @@ -4052,15 +4297,14 @@ dependencies = [ ] [[package]] -name = "tokio-rustls" -version = "0.13.1" +name = "tokio-macros" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "futures-core", - "rustls 0.17.0", - "tokio", - "webpki", + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", ] [[package]] @@ -4071,8 +4315,19 @@ checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a" dependencies = [ "futures-core", "rustls 0.18.1", - "tokio", - "webpki", + "tokio 0.2.25", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio 1.42.1", + "webpki 0.22.4", ] [[package]] @@ -4085,7 +4340,7 @@ dependencies = [ "either", "futures 0.3.31", "thiserror", - "tokio", + "tokio 0.2.25", ] [[package]] @@ -4095,7 +4350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" dependencies = [ "native-tls", - "tokio", + "tokio 0.2.25", ] [[package]] @@ -4109,7 +4364,20 @@ dependencies = [ "futures-sink", "log", "pin-project-lite 0.1.12", - "tokio", + "tokio 0.2.25", +] + +[[package]] +name = "tokio-util" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +dependencies = [ + "bytes 1.8.0", + "futures-core", + "futures-sink", + "pin-project-lite 0.2.15", + "tokio 1.42.1", ] [[package]] @@ -4203,7 +4471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" dependencies = [ "serde", - "tinystr", + "tinystr 0.7.6", ] [[package]] @@ -4212,12 +4480,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" version = "1.0.13" @@ -4283,16 +4545,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] -name = "url" -version = "2.5.2" +name = "untrusted" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -4443,8 +4718,18 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", ] [[package]] @@ -4453,7 +4738,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" dependencies = [ - "webpki", + "webpki 0.21.4", ] [[package]] @@ -4508,6 +4793,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -4526,6 +4817,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -4599,6 +4899,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -4637,6 +4943,29 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -4658,6 +4987,27 @@ dependencies = [ "syn 2.0.86", ] +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -4678,6 +5028,39 @@ dependencies = [ "syn 2.0.86", ] +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2 1.0.89", + "quote 1.0.37", + "syn 2.0.86", +] + [[package]] name = "zip" version = "0.5.13" diff --git a/Cargo.toml b/Cargo.toml index a70b09a..e90314a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ keywords = [ "crypto", "grin", "mimblewimble" ] readme = "README.md" exclude = ["**/*.grin", "**/*.grin2"] build = "src/build/build.rs" -edition = "2018" +edition = "2021" [[bin]] name = "grin-wallet" @@ -41,10 +41,10 @@ grin_wallet_util = { path = "./util", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_keychain = "5.3.3" -grin_util = "5.3.3" -grin_api = "5.3.3" +grin_core = "5.4.0" +grin_keychain = "5.4.0" +grin_util = "5.4.0" +grin_api = "5.4.0" # For beta release @@ -68,7 +68,7 @@ grin_api = "5.3.3" ###### [build-dependencies] -built = { version = "0.7", features = ["git2"]} +built = { version = "0.8.0", features = ["git2"]} [dev-dependencies] url = "2.1" diff --git a/api/Cargo.toml b/api/Cargo.toml index d2f1f2f..a85781e 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] exclude = ["**/*.grin", "**/*.grin2"] -edition = "2018" +edition = "2021" [dependencies] log = "0.4" @@ -30,9 +30,9 @@ grin_wallet_util = { path = "../util", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_keychain = "5.3.3" -grin_util = "5.3.3" +grin_core = "5.4.0" +grin_keychain = "5.4.0" +grin_util = "5.4.0" # For beta release diff --git a/api/src/foreign.rs b/api/src/foreign.rs index 2d70e63..0eb6ef1 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -150,7 +150,7 @@ where /// // These traits can be replaced with alternative implementations if desired /// /// let mut wallet = Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap()) - /// as Box, HTTPNodeClient, ExtKeychain>>; + /// as Box, HTTPNodeClient, ExtKeychain>>; /// /// // Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc... /// let lc = wallet.lc_provider().unwrap(); @@ -540,7 +540,7 @@ macro_rules! doctest_helper_setup_doc_env_foreign { DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(), ) as Box< - WalletInst< + dyn WalletInst< 'static, DefaultLCProvider, HTTPNodeClient, diff --git a/api/src/owner.rs b/api/src/owner.rs index 8d4fee2..ba2b3ab 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -158,7 +158,7 @@ where /// // These traits can be replaced with alternative implementations if desired /// /// let mut wallet = Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap()) - /// as Box, HTTPNodeClient, ExtKeychain>>; + /// as Box, HTTPNodeClient, ExtKeychain>>; /// /// // Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc... /// let lc = wallet.lc_provider().unwrap(); @@ -2719,7 +2719,7 @@ macro_rules! doctest_helper_setup_doc_env { DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(), ) as Box< - WalletInst< + dyn WalletInst< 'static, DefaultLCProvider, HTTPNodeClient, diff --git a/config/Cargo.toml b/config/Cargo.toml index 9d329c7..f646b3d 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] workspace = ".." -edition = "2018" +edition = "2021" [dependencies] rand = "0.6" @@ -21,8 +21,8 @@ grin_wallet_util = { path = "../util", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_util = "5.3.3" +grin_core = "5.4.0" +grin_util = "5.4.0" # For beta release diff --git a/config/src/comments.rs b/config/src/comments.rs index 4ae9f1b..c027042 100644 --- a/config/src/comments.rs +++ b/config/src/comments.rs @@ -333,10 +333,9 @@ pub fn migrate_comments( None } false => { - let comments: String = - vec_old_conf.iter().map(|s| s.chars()).flatten().collect(); + let comments: String = vec_old_conf.iter().flat_map(|s| s.chars()).collect(); let key = get_key(line_nospace); - match !(key == "NOT_FOUND") { + match key != "NOT_FOUND" { true => { vec_old_conf.clear(); hm_key_cmt_old.insert(key.clone(), comments); @@ -356,10 +355,10 @@ pub fn migrate_comments( .filter_map(|line| { let line_nospace = line.trim(); let is_ascii_control = line_nospace.chars().all(|x| x.is_ascii_control()); - match !(line.contains("#") || is_ascii_control) { + match !line.contains("#") && !is_ascii_control { true => { let key = get_key(line_nospace); - match !(key == "NOT_FOUND") { + match key != "NOT_FOUND" { true => Some((key, line_nospace.to_string())), false => None, } diff --git a/config/src/config.rs b/config/src/config.rs index d112980..2c37ae7 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -14,16 +14,6 @@ //! Configuration file management -use dirs; -use rand::distributions::{Alphanumeric, Distribution}; -use rand::thread_rng; -use std::env; -use std::fs::{self, File}; -use std::io::prelude::*; -use std::io::BufReader; -use std::path::PathBuf; -use toml; - use crate::comments::{insert_comments, migrate_comments}; use crate::core::global; use crate::types::{ @@ -31,11 +21,20 @@ use crate::types::{ }; use crate::types::{TorConfig, WalletConfig}; use crate::util::logger::LoggingConfig; +use rand::distributions::{Alphanumeric, Distribution}; +use rand::thread_rng; +use std::env; +use std::fs::{self, File}; +use std::io::prelude::*; +use std::io::BufReader; +use std::path::{Path, PathBuf}; +use toml; /// Wallet configuration file name pub const WALLET_CONFIG_FILE_NAME: &str = "grin-wallet.toml"; const WALLET_LOG_FILE_NAME: &str = "grin-wallet.log"; -const GRIN_HOME: &str = ".grin"; +/// .grin folder, usually in home/.grin +pub const GRIN_HOME: &str = ".grin"; /// Wallet data directory pub const GRIN_WALLET_DIR: &str = "wallet_data"; /// Node API secret @@ -43,31 +42,85 @@ pub const API_SECRET_FILE_NAME: &str = ".foreign_api_secret"; /// Owner API secret pub const OWNER_API_SECRET_FILE_NAME: &str = ".owner_api_secret"; -fn get_grin_path( +/// Function to locate the wallet dir and grin-wallet.toml in the order +/// a) config in top-dir if provided, b) in working dir, c) default dir +/// Function to get wallet dir and create dirs if not existing +pub fn get_wallet_path( chain_type: &global::ChainTypes, create_path: bool, ) -> Result { - // Check if grin dir exists - let mut grin_path = match dirs::home_dir() { + // A - Detect grin-wallet.toml in working dir + let mut config_path = std::env::current_dir()?; + config_path.push(WALLET_CONFIG_FILE_NAME); + if create_path == false && config_path.exists() { + config_path.pop(); + println!("Detected 'grin-wallet.toml' in working dir - opening associated wallet"); + return Ok(config_path); + }; + // B - Select home directory + let mut wallet_path = match dirs::home_dir() { Some(p) => p, None => PathBuf::new(), }; - grin_path.push(GRIN_HOME); - grin_path.push(chain_type.shortname()); + wallet_path.push(GRIN_HOME); + wallet_path.push(chain_type.shortname()); // Create if the default path doesn't exist - if !grin_path.exists() && create_path { - fs::create_dir_all(grin_path.clone())?; + if !wallet_path.exists() && create_path { + fs::create_dir_all(wallet_path.clone())?; } - - if !grin_path.exists() { + // Throw an error if the path still does not exist + if !wallet_path.exists() { Err(ConfigError::PathNotFoundError(String::from( - grin_path.to_str().unwrap(), + wallet_path.to_str().unwrap(), ))) } else { - Ok(grin_path) + Ok(wallet_path) } } +/// Smart function to detect the nodes .foreign_api_secret file in the order +/// a) top-dir, b) home directory - create directory if needed +pub fn get_node_path( + data_path: Option, + chain_type: &global::ChainTypes, +) -> Result { + let node_path = match data_path { + // 1) A If top dir provided and api_secret exist, return top dir + Some(path) => { + let mut node_path = path; + node_path.push(GRIN_HOME); + node_path.push(chain_type.shortname()); + node_path.push(API_SECRET_FILE_NAME); + if node_path.exists() { + node_path.pop(); + Ok(node_path) + // 1) B If top dir exists, but no api_secret, return home dir + } else { + let mut node_path = match dirs::home_dir() { + Some(p) => p, + None => PathBuf::new(), + }; + node_path.push(GRIN_HOME); + node_path.push(chain_type.shortname()); + Ok(node_path) + } + } + // 2) If there is no top_dir provided, always return home dir + None => { + let mut node_path = match dirs::home_dir() { + Some(p) => p, + None => PathBuf::new(), + }; + node_path.push(GRIN_HOME); + node_path.push(chain_type.shortname()); + Ok(node_path) + } + }; + node_path +} + +/// Checks if config in current working dir +#[allow(dead_code)] fn check_config_current_dir(path: &str) -> Option { let p = env::current_dir(); let mut c = match p { @@ -122,7 +175,7 @@ fn check_api_secret_file( ) -> Result<(), ConfigError> { let grin_path = match data_path { Some(p) => p, - None => get_grin_path(chain_type, false)?, + None => get_node_path(data_path, chain_type)?, }; let mut api_secret_path = grin_path; api_secret_path.push(file_name); @@ -133,55 +186,99 @@ fn check_api_secret_file( } } -/// Handles setup and detection of paths for wallet +/// Initial wallet setup does the following +/// 1) Load wallet config if run without 'init' 2) create wallet if run with 'init'' +/// Try in thiss order a) current dir as template, b) in top path, or c) .grin home +/// - load default config values +/// - update the wallet and node dir to the correct paths +/// - if grin-wallet.toml exists, but the wallet data dir does not, load config and continue wallet generation +/// - Automatically detect grin-wallet.toml in current directory pub fn initial_setup_wallet( chain_type: &global::ChainTypes, - data_path: Option, + mut data_path: Option, create_path: bool, ) -> Result { - if create_path { - if let Some(p) = data_path.clone() { - fs::create_dir_all(p)?; + // Fixing the input path when run with -here or -t (top-dir) + // - Fix top-dir path to compensate for bug on Linux to handle "\" + // - Convert top-dir path to be always absolute for config generation + // - Fix for Windows 10/11 to strip the '\\?\' prefix added to the path + if let Some(p) = &data_path { + if let Some(p_str) = p.to_str() { + let fixed_str = p_str.replace("\\", "/"); + let fixed_path = PathBuf::from(fixed_str); + if create_path { + fs::create_dir_all(&fixed_path)?; + } + let absolute_path = if fixed_path.is_absolute() { + fixed_path.canonicalize()? + } else { + env::current_dir()?.join(&fixed_path).canonicalize()? + }; + let absolute_path = + std::path::PathBuf::from(absolute_path.to_str().unwrap().replace(r"\\?\", "")); + data_path = Some(absolute_path); // Store the updated path } } - // Use config file if current directory if it exists, .grin home otherwise - let (path, config) = if let Some(p) = check_config_current_dir(WALLET_CONFIG_FILE_NAME) { - let mut path = p.clone(); - path.pop(); - (path, GlobalWalletConfig::new(p.to_str().unwrap())?) - } else { - // Check if grin dir exists - let grin_path = match data_path { - Some(p) => p, - None => get_grin_path(chain_type, create_path)?, - }; - // Get path to default config file - let mut config_path = grin_path.clone(); - config_path.push(WALLET_CONFIG_FILE_NAME); + // Get wallet data_dir path if none provided + let wallet_path = match data_path { + Some(p) => p, + None => get_wallet_path(chain_type, create_path)?, + }; + println!("Wallet path: {}", wallet_path.display()); + // Get path to the node directory, + let node_path = get_node_path(Some(wallet_path.clone()), chain_type)?; - // Return defaults if file doesn't exist - match config_path.clone().exists() { - false => { - let mut default_config = GlobalWalletConfig::for_chain(chain_type); - default_config.config_file_path = Some(config_path); - // update paths relative to current dir - default_config.update_paths(&grin_path); - (grin_path, default_config) + // Get config path and data path + let mut config_path = wallet_path.clone(); + config_path.push(WALLET_CONFIG_FILE_NAME); + let mut data_dir = wallet_path.clone(); + data_dir.push(GRIN_WALLET_DIR); + // Check if a config exists in theworking dir, if so load it + let (path, config) = match config_path.clone().exists() { + // If the config does not exist, load default and updated node and wallet dir + false => { + let mut default_config = GlobalWalletConfig::for_chain(chain_type); + default_config.config_file_path = Some(config_path.clone()); + default_config.update_paths(&wallet_path, &node_path); + + // Write config file + let res = + default_config.write_to_file(config_path.to_str().unwrap(), false, None, None); + + if let Err(e) = res { + let msg = format!( + "Error creating config file as ({}): {}", + config_path.to_str().unwrap(), + e + ); + return Err(ConfigError::SerializationError(msg)); } - true => { - let mut path = config_path.clone(); - path.pop(); - ( - path, - GlobalWalletConfig::new(config_path.to_str().unwrap())?, - ) + + (wallet_path, default_config) + } + + // Return config if not run with init + true => { + // If run with init and seed does not yet exists, continue, else throw error + if data_dir.exists() && create_path == true { + let msg = format!( + "{} already exists in the target directory ({}). Please remove it first", + config_path.to_str().unwrap(), + data_dir.to_str().unwrap(), + ); + return Err(ConfigError::SerializationError(msg)); + } else { + let config = GlobalWalletConfig::new(config_path.to_str().unwrap())?; + (wallet_path, config) } } }; + // Check API secrets, if ok, return config check_api_secret_file(chain_type, Some(path.clone()), OWNER_API_SECRET_FILE_NAME)?; check_api_secret_file(chain_type, Some(path), API_SECRET_FILE_NAME)?; + Ok(config) } @@ -211,7 +308,7 @@ impl GlobalWalletConfig { pub fn for_chain(chain_type: &global::ChainTypes) -> GlobalWalletConfig { let mut defaults_conf = GlobalWalletConfig::default(); let defaults = &mut defaults_conf.members.as_mut().unwrap().wallet; - defaults.chain_type = Some(chain_type.clone()); + defaults.chain_type = Some(*chain_type); match *chain_type { global::ChainTypes::Mainnet => {} @@ -268,21 +365,22 @@ impl GlobalWalletConfig { } /// Update paths - pub fn update_paths(&mut self, wallet_home: &PathBuf) { - let mut wallet_path = wallet_home.clone(); - wallet_path.push(GRIN_WALLET_DIR); - self.members.as_mut().unwrap().wallet.data_file_dir = - wallet_path.to_str().unwrap().to_owned(); - let mut secret_path = wallet_home.clone(); - secret_path.push(OWNER_API_SECRET_FILE_NAME); - self.members.as_mut().unwrap().wallet.api_secret_path = - Some(secret_path.to_str().unwrap().to_owned()); - let mut node_secret_path = wallet_home.clone(); + pub fn update_paths(&mut self, wallet_home: &PathBuf, node_home: &Path) { + let mut data_file_dir = wallet_home.to_path_buf(); + let mut node_secret_path = node_home.to_path_buf(); + let mut secret_path = wallet_home.to_path_buf(); + let mut log_path = wallet_home.to_path_buf(); + let tor_path = wallet_home.to_path_buf(); node_secret_path.push(API_SECRET_FILE_NAME); + data_file_dir.push(GRIN_WALLET_DIR); + secret_path.push(OWNER_API_SECRET_FILE_NAME); + log_path.push(WALLET_LOG_FILE_NAME); + self.members.as_mut().unwrap().wallet.data_file_dir = + data_file_dir.to_str().unwrap().to_owned(); self.members.as_mut().unwrap().wallet.node_api_secret_path = Some(node_secret_path.to_str().unwrap().to_owned()); - let mut log_path = wallet_home.clone(); - log_path.push(WALLET_LOG_FILE_NAME); + self.members.as_mut().unwrap().wallet.api_secret_path = + Some(secret_path.to_str().unwrap().to_owned()); self.members .as_mut() .unwrap() @@ -290,7 +388,6 @@ impl GlobalWalletConfig { .as_mut() .unwrap() .log_file_path = log_path.to_str().unwrap().to_owned(); - let tor_path = wallet_home.clone(); self.members .as_mut() .unwrap() @@ -339,7 +436,7 @@ impl GlobalWalletConfig { ) -> Result { let config: GlobalWalletConfigMembers = toml::from_str(&GlobalWalletConfig::fix_warning_level(config_str.clone())).unwrap(); - if config.config_file_version != None { + if config.config_file_version.is_some() { return Ok(config_str); } let adjusted_config = GlobalWalletConfigMembers { @@ -347,7 +444,7 @@ impl GlobalWalletConfig { tor: Some(TorConfig { bridge: TorBridgeConfig::default(), proxy: TorProxyConfig::default(), - ..config.tor.unwrap_or(TorConfig::default()) + ..config.tor.unwrap_or_default() }), ..config }; diff --git a/controller/Cargo.toml b/controller/Cargo.toml index 33a9172..6a3a5ca 100644 --- a/controller/Cargo.toml +++ b/controller/Cargo.toml @@ -8,11 +8,11 @@ repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] exclude = ["**/*.grin", "**/*.grin2"] #build = "src/build/build.rs" -edition = "2018" +edition = "2021" [dependencies] futures = "0.3" -hyper = "0.13" +hyper = "0.14" rand = "0.7" serde = "1" serde_derive = "1" @@ -39,10 +39,10 @@ grin_wallet_config = { path = "../config", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_keychain = "5.3.3" -grin_util = "5.3.3" -grin_api = "5.3.3" +grin_core = "5.4.0" +grin_keychain = "5.4.0" +grin_util = "5.4.0" +grin_api = "5.4.0" # For beta release @@ -72,7 +72,7 @@ remove_dir_all = "0.7" ##### Grin Imports # For Release -grin_chain = "5.3.3" +grin_chain = "5.4.0" # For beta release diff --git a/controller/src/command.rs b/controller/src/command.rs index 31e4c4e..42098fb 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -77,6 +77,7 @@ pub struct InitArgs { pub restore: bool, } +/// Write config (default if None), initiate the wallet pub fn init( owner_api: &mut Owner, _g_args: &GlobalArgs, diff --git a/controller/tests/check.rs b/controller/tests/check.rs index 634cdd2..c9c5990 100644 --- a/controller/tests/check.rs +++ b/controller/tests/check.rs @@ -26,6 +26,7 @@ use grin_wallet_libwallet as libwallet; use impls::test_framework::{self, LocalWalletClient}; use impls::{PathToSlate, SlatePutter as _}; use libwallet::{InitTxArgs, NodeClient}; +use std::cmp; use std::sync::atomic::Ordering; use std::thread; use std::time::Duration; @@ -847,6 +848,200 @@ fn output_scanning_impl(test_dir: &'static str) -> Result<(), libwallet::Error> Ok(()) } +fn multi_batch_scan_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { + let mut wallet_proxy = create_wallet_proxy(test_dir); + let chain = wallet_proxy.chain.clone(); + let stopper = wallet_proxy.running.clone(); + + create_wallet_and_add!( + client1, + wallet1, + mask1_i, + test_dir, + "wallet1", + None, + &mut wallet_proxy, + false + ); + let mask1 = (&mask1_i).as_ref(); + + thread::spawn(move || { + if let Err(e) = wallet_proxy.run() { + error!("Wallet Proxy error: {}", e); + } + }); + + let reward = consensus::REWARD; + let bh = 12u64; + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); + + let mut output_commits = vec![]; + wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { + let (_, info) = api.retrieve_summary_info(m, true, 1)?; + assert_eq!(info.last_confirmed_height, bh); + assert_eq!(info.total, bh * reward); + output_commits = api.retrieve_outputs(m, false, true, None)?.1; + Ok(()) + })?; + + { + wallet_inst!(wallet1, w); + let mut batch = w.batch(mask1)?; + batch.delete(&output_commits[8].output.key_id, &None)?; + batch.commit()?; + } + + let tip = { + wallet_inst!(wallet1, w); + w.w2n_client().get_chain_tip()? + }; + + let start_height = 1; + let batch_size = 5; + let mut total_pmmr_range = None; + let mut batches = 0; + let status_send_channel = None; + for h in (start_height..tip.0).step_by((batch_size + 1) as usize) { + let batch_end_height = cmp::min(tip.0, h + batch_size); + let (mut info, range) = libwallet::scan( + wallet1.clone(), + mask1, + false, + h, + batch_end_height, + start_height, + tip.0, + total_pmmr_range, + &status_send_channel, + )?; + info.hash = if batch_end_height == tip.0 { + tip.1.clone() + } else { + "".to_owned() + }; + total_pmmr_range = Some(range); + batches += 1; + + wallet_inst!(wallet1, w); + let mut batch = w.batch(mask1)?; + batch.save_last_scanned_block(info)?; + batch.commit()?; + } + assert!(batches > 1); + + wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { + let (_, restored_outputs) = api.retrieve_outputs(m, false, true, None)?; + let (_, info) = api.retrieve_summary_info(m, false, 1)?; + assert_eq!(info.total, bh * reward); + assert_eq!(restored_outputs.len(), bh as usize); + Ok(()) + })?; + + stopper.store(false, Ordering::Relaxed); + thread::sleep(Duration::from_millis(200)); + Ok(()) +} + +fn restore_corrupted_outputs_across_batches_impl( + test_dir: &'static str, +) -> Result<(), libwallet::Error> { + let mut wallet_proxy = create_wallet_proxy(test_dir); + let chain = wallet_proxy.chain.clone(); + let stopper = wallet_proxy.running.clone(); + + create_wallet_and_add!( + client1, + wallet1, + mask1_i, + test_dir, + "wallet1", + None, + &mut wallet_proxy, + false + ); + let mask1 = (&mask1_i).as_ref(); + + thread::spawn(move || { + if let Err(e) = wallet_proxy.run() { + error!("Wallet Proxy error: {}", e); + } + }); + + let reward = consensus::REWARD; + let bh = 12u64; + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); + + let mut output_commits = vec![]; + wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { + let (_, info) = api.retrieve_summary_info(m, true, 1)?; + assert_eq!(info.total, bh * reward); + output_commits = api.retrieve_outputs(m, false, true, None)?.1; + Ok(()) + })?; + + { + wallet_inst!(wallet1, w); + let mut batch = w.batch(mask1)?; + batch.delete(&output_commits[2].output.key_id, &None)?; + batch.delete(&output_commits[8].output.key_id, &None)?; + batch.commit()?; + } + + let tip = { + wallet_inst!(wallet1, w); + w.w2n_client().get_chain_tip()? + }; + let status_send_channel = None; + let (info, _) = libwallet::scan( + wallet1.clone(), + mask1, + false, + 1, + 6, + 1, + tip.0, + None, + &status_send_channel, + )?; + { + wallet_inst!(wallet1, w); + { + let mut batch = w.batch(mask1)?; + batch.save_last_scanned_block(info)?; + batch.commit()?; + } + let last_scanned = w.last_scanned_block()?; + assert_eq!(last_scanned.height, 6); + assert_eq!(last_scanned.hash, ""); + } + + wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { + let (_, outputs_after_first_batch) = api.retrieve_outputs(m, false, false, None)?; + assert_eq!(outputs_after_first_batch.len(), (bh - 1) as usize); + + let (_, info) = api.retrieve_summary_info(m, true, 1)?; + let (_, restored_outputs) = api.retrieve_outputs(m, false, true, None)?; + let unique_keys = restored_outputs + .iter() + .map(|o| o.output.key_id.clone()) + .collect::>(); + + assert_eq!(info.total, bh * reward); + assert_eq!(restored_outputs.len(), bh as usize); + assert_eq!(unique_keys.len(), bh as usize); + assert!(restored_outputs + .iter() + .all(|o| o.output.status == libwallet::OutputStatus::Unspent)); + Ok(()) + })?; + + stopper.store(false, Ordering::Relaxed); + thread::sleep(Duration::from_millis(200)); + Ok(()) +} + #[test] fn scan() { let test_dir = "test_output/scan"; @@ -876,3 +1071,23 @@ fn output_scanning() { } clean_output_dir(test_dir); } + +#[test] +fn multi_batch_scan() { + let test_dir = "test_output/multi_batch_scan"; + setup(test_dir); + if let Err(e) = multi_batch_scan_impl(test_dir) { + panic!("Libwallet Error: {}", e); + } + clean_output_dir(test_dir); +} + +#[test] +fn restore_corrupted_outputs_across_batches() { + let test_dir = "test_output/restore_corrupted_outputs_across_batches"; + setup(test_dir); + if let Err(e) = restore_corrupted_outputs_across_batches_impl(test_dir) { + panic!("Libwallet Error: {}", e); + } + clean_output_dir(test_dir); +} diff --git a/controller/tests/common/mod.rs b/controller/tests/common/mod.rs index e015c5c..56d3d8d 100644 --- a/controller/tests/common/mod.rs +++ b/controller/tests/common/mod.rs @@ -102,8 +102,12 @@ pub fn setup_global_chain_type() { pub fn create_wallet_proxy( test_dir: &str, -) -> WalletProxy, LocalWalletClient, ExtKeychain> -{ +) -> WalletProxy< + '_, + DefaultLCProvider<'_, LocalWalletClient, ExtKeychain>, + LocalWalletClient, + ExtKeychain, +> { WalletProxy::new(test_dir) } diff --git a/controller/tests/transaction.rs b/controller/tests/transaction.rs index fa34014..33db4c9 100644 --- a/controller/tests/transaction.rs +++ b/controller/tests/transaction.rs @@ -442,7 +442,7 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { // few values to keep things shorter let reward = core::consensus::REWARD; let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height - // mine a few blocks + // mine a few blocks let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); let amount = 30_000_000_000; diff --git a/impls/Cargo.toml b/impls/Cargo.toml index 7689d61..6dfc918 100644 --- a/impls/Cargo.toml +++ b/impls/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] exclude = ["**/*.grin", "**/*.grin2"] -edition = "2018" +edition = "2021" [dependencies] blake2-rfc = "0.2" @@ -43,12 +43,12 @@ grin_wallet_libwallet = { path = "../libwallet", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_keychain = "5.3.3" -grin_chain = "5.3.3" -grin_util = "5.3.3" -grin_api = "5.3.3" -grin_store = "5.3.3" +grin_core = "5.4.0" +grin_keychain = "5.4.0" +grin_chain = "5.4.0" +grin_util = "5.4.0" +grin_api = "5.4.0" +grin_store = "5.4.0" # For beta release diff --git a/impls/src/backends/lmdb.rs b/impls/src/backends/lmdb.rs index e50f2b2..6d82f27 100644 --- a/impls/src/backends/lmdb.rs +++ b/impls/src/backends/lmdb.rs @@ -726,6 +726,16 @@ where Ok(()) } + fn delete_tx_log_entry(&mut self, tx_id: u32, parent_id: &Identifier) -> Result<(), Error> { + let tx_log_key = to_key_u64( + TX_LOG_ENTRY_PREFIX, + &mut parent_id.to_bytes().to_vec(), + tx_id as u64, + ); + self.db.borrow().as_ref().unwrap().delete(&tx_log_key)?; + Ok(()) + } + fn save_acct_path(&mut self, mapping: AcctPathMapping) -> Result<(), Error> { let acct_key = to_key( ACCOUNT_PATH_MAPPING_PREFIX, diff --git a/impls/src/lifecycle/default.rs b/impls/src/lifecycle/default.rs index d0cc606..0b24b68 100644 --- a/impls/src/lifecycle/default.rs +++ b/impls/src/lifecycle/default.rs @@ -27,6 +27,15 @@ use crate::LMDBBackend; use grin_util::logger::LoggingConfig; use std::fs; use std::path::PathBuf; +use std::path::MAIN_SEPARATOR; + +// Helper fuction to format paths according to OS, avoids bugs on Linux +pub fn fmt_path(path: String) -> String { + let sep = &MAIN_SEPARATOR.to_string(); + let path = path.replace("/", &sep); + let path = path.replace("\\", &sep); + path +} pub struct DefaultLCProvider<'a, C, K> where @@ -64,7 +73,13 @@ where } fn get_top_level_directory(&self) -> Result { - Ok(self.data_dir.to_owned()) + let sep = &MAIN_SEPARATOR.to_string(); + let data_dir = self + .data_dir + .to_owned() + .replace("/", &sep) + .replace("\\", &sep); + Ok(data_dir) } fn create_config( @@ -87,11 +102,12 @@ where None => None, }, }; - let wallet = match wallet_config { - Some(w) => w, + // Check if config was provided, if not load default and set update to "true" + let (wallet, update) = match wallet_config { + Some(w) => (w, false), None => match default_config.members.as_ref() { - Some(m) => m.clone().wallet, - None => WalletConfig::default(), + Some(m) => (m.clone().wallet, true), + None => (WalletConfig::default(), true), }, }; let tor = match tor_config { @@ -113,13 +129,6 @@ where let mut config_file_name = PathBuf::from(self.data_dir.clone()); config_file_name.push(file_name); - // create top level dir if it doesn't exist - let dd = PathBuf::from(self.data_dir.clone()); - if !dd.exists() { - // try create - fs::create_dir_all(dd)?; - } - let mut data_dir_name = PathBuf::from(self.data_dir.clone()); data_dir_name.push(GRIN_WALLET_DIR); @@ -132,15 +141,26 @@ where return Err(Error::Lifecycle(msg)); } - // just leave as is if file exists but there's no data dir + // If config exists but the datadir return ok if config_file_name.exists() { return Ok(()); } + // default settings are updated if no config was provided, no support for top_dir/here + let mut abs_path_node = std::env::current_dir()?; + abs_path_node.push(self.data_dir.clone()); + let mut absolute_path_wallet = std::env::current_dir()?; + absolute_path_wallet.push(self.data_dir.clone()); - let mut abs_path = std::env::current_dir()?; - abs_path.push(self.data_dir.clone()); - - default_config.update_paths(&abs_path); + // if no config provided, update defaults + if update == true { + // create top level dir if it doesn't exist + let dd = PathBuf::from(self.data_dir.clone()); + if !dd.exists() { + // try create + fs::create_dir_all(dd)?; + default_config.update_paths(&abs_path_node, &absolute_path_wallet); + } + }; let res = default_config.write_to_file(config_file_name.to_str().unwrap(), false, None, None); if let Err(e) = res { @@ -178,7 +198,7 @@ where ) -> Result<(), Error> { let mut data_dir_name = PathBuf::from(self.data_dir.clone()); data_dir_name.push(GRIN_WALLET_DIR); - let data_dir_name = data_dir_name.to_str().unwrap(); + let data_dir_name = fmt_path((data_dir_name.to_str().unwrap()).to_string()); let exists = WalletSeed::seed_file_exists(&data_dir_name); if !test_mode { if let Ok(true) = exists { @@ -226,7 +246,7 @@ where ) -> Result, Error> { let mut data_dir_name = PathBuf::from(self.data_dir.clone()); data_dir_name.push(GRIN_WALLET_DIR); - let data_dir_name = data_dir_name.to_str().unwrap(); + let data_dir_name = fmt_path(data_dir_name.to_str().unwrap().to_string()); let mut wallet: LMDBBackend<'a, C, K> = match LMDBBackend::new(&data_dir_name, self.node_client.clone()) { Err(e) => { @@ -271,7 +291,7 @@ where ) -> Result { let mut data_dir_name = PathBuf::from(self.data_dir.clone()); data_dir_name.push(GRIN_WALLET_DIR); - let data_dir_name = data_dir_name.to_str().unwrap(); + let data_dir_name = fmt_path(data_dir_name.display().to_string()); let wallet_seed = WalletSeed::from_file(&data_dir_name, password) .map_err(|_| Error::Lifecycle("Error opening wallet seed file".into()))?; let res = wallet_seed diff --git a/impls/src/lifecycle/seed.rs b/impls/src/lifecycle/seed.rs index e7b6b46..59dcd34 100644 --- a/impls/src/lifecycle/seed.rs +++ b/impls/src/lifecycle/seed.rs @@ -12,16 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::blake2; use core::num::NonZeroU32; +use rand::{thread_rng, Rng}; +use serde_json; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::Path; use std::path::MAIN_SEPARATOR; -use crate::blake2; -use rand::{thread_rng, Rng}; -use serde_json; - use ring::aead; use ring::pbkdf2; @@ -57,6 +56,13 @@ impl WalletSeed { self.0.to_vec().to_hex() } + // Helper fuction to format paths according to OS, avoids bugs on Linux + pub fn fmt_path(path: String) -> String { + let sep = &MAIN_SEPARATOR.to_string(); + let path = path.replace("/", &sep); + let path = path.replace("\\", &sep); + path + } pub fn to_mnemonic(&self) -> Result { let result = mnemonic::from_entropy(&self.0); match result { @@ -97,7 +103,12 @@ impl WalletSeed { } pub fn seed_file_exists(data_file_dir: &str) -> Result { - let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); + let seed_file_path = &format!( + "{}{}{}", + Self::fmt_path(data_file_dir.to_string()), + MAIN_SEPARATOR, + SEED_FILE, + ); debug!("Seed file path: {}", seed_file_path); if Path::new(seed_file_path).exists() { Ok(true) @@ -132,7 +143,12 @@ impl WalletSeed { word_list: util::ZeroingString, password: util::ZeroingString, ) -> Result<(), Error> { - let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); + let seed_file_path = &format!( + "{}{}{}", + Self::fmt_path(data_file_dir.to_string()), + MAIN_SEPARATOR, + SEED_FILE, + ); debug!("data file dir: {}", data_file_dir); if let Ok(true) = WalletSeed::seed_file_exists(data_file_dir) { debug!("seed file exists"); @@ -166,10 +182,15 @@ impl WalletSeed { // create directory if it doesn't exist fs::create_dir_all(data_file_dir).map_err(|_| Error::IO)?; - let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); - + let seed_file_path = &format!( + "{}{}{}", + Self::fmt_path(data_file_dir.to_string()), + MAIN_SEPARATOR, + SEED_FILE, + ); + let data_file_dir = Self::fmt_path(data_file_dir.to_string()); warn!("Generating wallet seed file at: {}", seed_file_path); - let exists = WalletSeed::seed_file_exists(data_file_dir)?; + let exists = WalletSeed::seed_file_exists(&data_file_dir)?; if exists && !test_mode { let msg = format!("Wallet seed already exists at: {}", data_file_dir); error!("{}", msg); @@ -196,7 +217,12 @@ impl WalletSeed { // create directory if it doesn't exist fs::create_dir_all(data_file_dir).map_err(|_| Error::IO)?; - let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); + let seed_file_path = &format!( + "{}{}{}", + Self::fmt_path(data_file_dir.to_string()), + MAIN_SEPARATOR, + SEED_FILE, + ); debug!("Using wallet seed file at: {}", seed_file_path); @@ -219,7 +245,12 @@ impl WalletSeed { } pub fn delete_seed_file(data_file_dir: &str) -> Result<(), Error> { - let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); + let seed_file_path = &format!( + "{}{}{}", + Self::fmt_path(data_file_dir.to_string()), + MAIN_SEPARATOR, + SEED_FILE, + ); if Path::new(seed_file_path).exists() { debug!("Deleting wallet seed file at: {}", seed_file_path); fs::remove_file(seed_file_path).map_err(|_| Error::IO)?; diff --git a/impls/src/node_clients/http.rs b/impls/src/node_clients/http.rs index 66efeb7..6b80b49 100644 --- a/impls/src/node_clients/http.rs +++ b/impls/src/node_clients/http.rs @@ -142,7 +142,8 @@ impl NodeClient for HTTPNodeClient { verified: Some(false), }); } else { - error!("Unable to contact Node to get version info: {}", e); + error!("Unable to contact Node to get version info: {}, check your node is running", e); + warn!("Warning: a) Node is offline, or b) 'node_api_secret_path' in 'grin-wallet.toml' is set incorrectly"); return None; } } diff --git a/integration/Cargo.toml b/integration/Cargo.toml index a624573..1230be2 100644 --- a/integration/Cargo.toml +++ b/integration/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/mimblewimble/grin" keywords = [ "crypto", "grin", "mimblewimble" ] workspace = ".." -edition = "2018" +edition = "2021" [dependencies] hyper = "0.12" diff --git a/libwallet/Cargo.toml b/libwallet/Cargo.toml index 684ddf2..336fad0 100644 --- a/libwallet/Cargo.toml +++ b/libwallet/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] exclude = ["**/*.grin", "**/*.grin2"] #build = "src/build/build.rs" -edition = "2018" +edition = "2021" [dependencies] blake2-rfc = "0.2" @@ -47,10 +47,10 @@ grin_wallet_config = { path = "../config", version = "5.4.0-alpha.1" } ##### Grin Imports # For Release -grin_core = "5.3.3" -grin_keychain = "5.3.3" -grin_util = "5.3.3" -grin_store = "5.3.3" +grin_core = "5.4.0" +grin_keychain = "5.4.0" +grin_util = "5.4.0" +grin_store = "5.4.0" # For beta release diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index 9eda629..0d5fd0a 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -14,6 +14,7 @@ //! Generic implementation of owner API functions +use std::cmp; use uuid::Uuid; use crate::api_impl::foreign::finalize_tx as foreign_finalize; @@ -1122,25 +1123,35 @@ where w.w2n_client().get_chain_tip()? }; - let start_height = match start_height { - Some(h) => h, - None => 1, - }; + let start_height = start_height.unwrap_or_else(|| 1); - let mut info = scan::scan( - wallet_inst.clone(), - keychain_mask, - delete_unconfirmed, - start_height, - tip.0, - status_send_channel, - )?; - info.hash = tip.1; + // Scan every 10k heights to save data between batches in case of interruption. + let mut total_pmmr_range = None; + for h in (start_height..tip.0).step_by(10001) { + let batch_end_height = cmp::min(tip.0, h + 10000); + let (mut info, range) = scan::scan( + wallet_inst.clone(), + keychain_mask, + delete_unconfirmed, + h, + batch_end_height, + start_height, + tip.0, + total_pmmr_range, + status_send_channel, + )?; + info.hash = if batch_end_height == tip.0 { + tip.1.clone() + } else { + "".to_owned() + }; + total_pmmr_range = Some(range); - wallet_lock!(wallet_inst, w); - let mut batch = w.batch(keychain_mask)?; - batch.save_last_scanned_block(info)?; - batch.commit()?; + wallet_lock!(wallet_inst, w); + let mut batch = w.batch(keychain_mask)?; + batch.save_last_scanned_block(info)?; + batch.commit()?; + } Ok(()) } @@ -1180,6 +1191,9 @@ where } } +/// Wallet scan window in blocks (48 hours). +pub const REORG_RESCAN_WINDOW: u64 = 24 * 60 * 2; + /// Experimental, wrap the entire definition of how a wallet's state is updated pub fn update_wallet_state<'a, L, C, K>( wallet_inst: Arc>>>, @@ -1258,23 +1272,24 @@ where let last_scanned_block = { wallet_lock!(wallet_inst, w); match w.init_status()? { - WalletInitStatus::InitNeedsScanning => ScannedBlockInfo { - height: 0, - hash: "".to_owned(), - start_pmmr_index: 0, - last_pmmr_index: 0, - }, WalletInitStatus::InitNoScanning => ScannedBlockInfo { height: tip.clone().0, hash: tip.clone().1, start_pmmr_index: 0, last_pmmr_index: 0, }, - WalletInitStatus::InitComplete => w.last_scanned_block()?, + _ => w.last_scanned_block()?, } }; - let start_index = last_scanned_block.height.saturating_sub(100); + let start_height = last_scanned_block + .height + .saturating_sub(REORG_RESCAN_WINDOW); + + debug!( + "update_wallet_state: last_scanned_block: {:?}", + last_scanned_block + ); if last_scanned_block.height == 0 { let msg = "This wallet has not been scanned against the current chain. Beginning full scan... (this first scan may take a while, but subsequent scans will be much quicker)".to_string(); @@ -1283,18 +1298,28 @@ where } } - let mut info = scan::scan( - wallet_inst.clone(), - keychain_mask, - false, - start_index, - tip.0, - status_send_channel, - )?; + // Scan every 10k heights to save data between batches in case of interruption. + let mut total_pmmr_range = None; + for h in (start_height..tip.0).step_by(10001) { + let batch_end_height = cmp::min(tip.0, h + 10000); + let (mut info, range) = scan::scan( + wallet_inst.clone(), + keychain_mask, + false, + h, + batch_end_height, + start_height, + tip.0, + total_pmmr_range, + status_send_channel, + )?; + info.hash = if batch_end_height == tip.0 { + tip.1.clone() + } else { + "".to_owned() + }; + total_pmmr_range = Some(range); - info.hash = tip.1; - - { wallet_lock!(wallet_inst, w); let mut batch = w.batch(keychain_mask)?; batch.save_last_scanned_block(info)?; diff --git a/libwallet/src/internal/scan.rs b/libwallet/src/internal/scan.rs index 129e99c..955674f 100644 --- a/libwallet/src/internal/scan.rs +++ b/libwallet/src/internal/scan.rs @@ -229,26 +229,30 @@ where fn collect_chain_outputs<'a, C, K>( keychain: &K, client: C, + batch_start_index: u64, + batch_end_index: u64, start_index: u64, - end_index: Option, + end_index: u64, status_send_channel: &Option>, -) -> Result<(Vec, u64), Error> +) -> Result<(Vec, u64, u8), Error> where C: NodeClient + 'a, K: Keychain + 'a, { let batch_size = 1000; let start_index_stat = start_index; - let mut start_index = start_index; + let mut start_index = batch_start_index; let mut result_vec: Vec = vec![]; let last_retrieved_return_index; + + let mut perc_complete; loop { let (highest_index, last_retrieved_index, outputs) = - client.get_outputs_by_pmmr_index(start_index, end_index, batch_size)?; + client.get_outputs_by_pmmr_index(start_index, Some(batch_end_index), batch_size)?; - let range = highest_index as f64 - start_index_stat as f64; + let range = end_index as f64 - start_index_stat as f64; let progress = last_retrieved_index as f64 - start_index_stat as f64; - let perc_complete = cmp::min(((progress / range) * 100.0) as u8, 99); + perc_complete = cmp::min(((progress / range) * 100.0) as u8, 99); let msg = format!( "Checking {} outputs, up to index {}. (Highest index: {})", @@ -264,16 +268,21 @@ where keychain, outputs.clone(), status_send_channel, - perc_complete as u8, + perc_complete, )?); + debug!( + "collect_chain_outputs: start_index {}, last_pmmr_index {}", + start_index, last_retrieved_index + ); + if highest_index <= last_retrieved_index { last_retrieved_return_index = last_retrieved_index; break; } start_index = last_retrieved_index + 1; } - Ok((result_vec, last_retrieved_return_index)) + Ok((result_vec, last_retrieved_return_index, perc_complete)) } /// @@ -451,17 +460,30 @@ where Ok(chain_outs) } -/// Check / repair wallet contents by scanning against chain -/// assume wallet contents have been freshly updated with contents -/// of latest block +/// Scan chain outputs and repair the wallet state where needed. +/// +/// This is the low-level worker used by the owner API. Callers should normally +/// use the owner scan/update methods instead of calling this directly, unless +/// they need to drive a scan in batches and save progress between those batches. +/// +/// `batch_start_height` and `batch_end_height` describe the part of the chain +/// scanned by this call. `start_height` and `end_height` describe the full scan +/// range, so progress and PMMR bounds still reflect the whole scan. +/// +/// The returned `ScannedBlockInfo` is the progress marker to persist after the +/// batch. The returned PMMR range can be passed into the next batch to avoid +/// looking up the full range again. pub fn scan<'a, L, C, K>( wallet_inst: Arc>>>, keychain_mask: Option<&SecretKey>, delete_unconfirmed: bool, + batch_start_height: u64, + batch_end_height: u64, start_height: u64, end_height: u64, + total_pmmr_range: Option<(u64, u64)>, status_send_channel: &Option>, -) -> Result +) -> Result<(ScannedBlockInfo, (u64, u64)), Error> where L: WalletLCProvider<'a, C, K>, C: NodeClient + 'a, @@ -469,30 +491,46 @@ where { // First, get a definitive list of outputs we own from the chain if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning("Starting UTXO scan".to_owned(), 0)); + if start_height == batch_start_height { + let _ = s.send(StatusMessage::Scanning("Starting UTXO scan".to_owned(), 0)); + } } let (client, keychain) = { wallet_lock!(wallet_inst, w); (w.w2n_client().clone(), w.keychain(keychain_mask)?) }; - // Retrieve the actual PMMR index range we're looking for - let pmmr_range = client.height_range_to_pmmr_indices(start_height, Some(end_height))?; + // Retrieve total PMMR index range we're looking for + let total_pmmr_range = if let Some(total_range) = total_pmmr_range { + total_range + } else { + client.height_range_to_pmmr_indices(start_height, Some(end_height))? + }; - let (chain_outs, last_index) = collect_chain_outputs( + // Retrieve current batch PMMR index range + let pmmr_range = + client.height_range_to_pmmr_indices(batch_start_height, Some(batch_end_height))?; + + debug!( + "scan: from: {}, to: {}", + batch_start_height, batch_end_height + ); + + let (chain_outs, last_index, perc_complete) = collect_chain_outputs( &keychain, client, pmmr_range.0, - Some(pmmr_range.1), + pmmr_range.1, + total_pmmr_range.0, + total_pmmr_range.1, status_send_channel, )?; let msg = format!( "Identified {} wallet_outputs as belonging to this wallet", chain_outs.len(), ); - if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } // Now, get all outputs owned by this wallet (regardless of account) @@ -530,7 +568,7 @@ where o.value, o.key_id, m.1.commit, ); if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } o.status = OutputStatus::Unspent; // any transactions associated with this should be cancelled @@ -551,7 +589,7 @@ where m.value, m.key_id, m.commit, m.mmr_index ); if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } restore_missing_output( wallet_inst.clone(), @@ -572,7 +610,7 @@ where o.value, o.key_id, m.1.commit, ); if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } o.status = OutputStatus::Unspent; cancel_tx_log_entry(wallet_inst.clone(), keychain_mask, &o)?; @@ -595,7 +633,7 @@ where o.value, o.key_id, m.commit, ); if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } cancel_tx_log_entry(wallet_inst.clone(), keychain_mask, &o)?; wallet_lock!(wallet_inst, w); @@ -616,7 +654,7 @@ where let label = format!("{}_{}", label_base, acct_index); let msg = format!("Setting account {} at path {}", label, path); if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::Scanning(msg, 99)); + let _ = s.send(StatusMessage::Scanning(msg, perc_complete)); } keys::set_acct_path(&mut **w, keychain_mask, &label, path)?; acct_index += 1; @@ -631,15 +669,20 @@ where } if let Some(ref s) = status_send_channel { - let _ = s.send(StatusMessage::ScanningComplete( - "Scanning Complete".to_owned(), - )); + if end_height == batch_end_height { + let _ = s.send(StatusMessage::ScanningComplete( + "Scanning Complete".to_owned(), + )); + } } - Ok(ScannedBlockInfo { - height: end_height, - hash: "".to_owned(), - start_pmmr_index: pmmr_range.0, - last_pmmr_index: last_index, - }) + Ok(( + ScannedBlockInfo { + height: batch_end_height, + hash: "".to_owned(), + start_pmmr_index: pmmr_range.0, + last_pmmr_index: last_index, + }, + total_pmmr_range, + )) } diff --git a/libwallet/src/internal/updater.rs b/libwallet/src/internal/updater.rs index 3d5db43..9b4cd0a 100644 --- a/libwallet/src/internal/updater.rs +++ b/libwallet/src/internal/updater.rs @@ -96,6 +96,7 @@ where /// Apply advanced filtering to resultset from retrieve_txs below pub fn apply_advanced_tx_list_filtering<'a, T: ?Sized, C, K>( wallet: &mut T, + parent_key_id: Option<&Identifier>, query_args: &RetrieveTxQueryArgs, ) -> Vec where @@ -107,6 +108,10 @@ where let txs_iter: Box> = Box::new( wallet .tx_log_iter() + .filter(|tx_entry| match parent_key_id { + Some(k) => tx_entry.parent_key_id == *k, + None => true, + }) .filter(|tx_entry| { if let Some(v) = query_args.exclude_cancelled { if v { @@ -357,7 +362,7 @@ where // Adding in new transaction list query logic. If `tx_id` or `tx_slate_id` // is provided, then `query_args` is ignored and old logic is followed. if query_args.is_some() && tx_id.is_none() && tx_slate_id.is_none() { - txs = apply_advanced_tx_list_filtering(wallet, &query_args.unwrap()) + txs = apply_advanced_tx_list_filtering(wallet, parent_key_id, &query_args.unwrap()) } else { txs = wallet .tx_log_iter() diff --git a/libwallet/src/mwixnet/onion/crypto/dalek.rs b/libwallet/src/mwixnet/onion/crypto/dalek.rs index a10c65b..38fd408 100644 --- a/libwallet/src/mwixnet/onion/crypto/dalek.rs +++ b/libwallet/src/mwixnet/onion/crypto/dalek.rs @@ -117,11 +117,13 @@ impl Writeable for DalekPublicKey { } /// Encapsulates an ed25519_dalek::Signature and provides (de-)serialization +#[allow(dead_code)] #[derive(Clone, Debug, PartialEq)] pub struct DalekSignature(Signature); impl DalekSignature { /// Convert hex string to DalekSignature. + #[allow(dead_code)] pub fn from_hex(hex: &str) -> Result { let bytes = grin_util::from_hex(hex) .map_err(|_| DalekError::HexError(format!("failed to decode {}", hex)))?; @@ -131,6 +133,7 @@ impl DalekSignature { } /// Verifies DalekSignature + #[allow(dead_code)] pub fn verify(&self, pk: &DalekPublicKey, msg: &[u8]) -> Result<(), DalekError> { pk.as_ref() .verify(&msg, &self.0) diff --git a/libwallet/src/types.rs b/libwallet/src/types.rs index 27597da..35a3392 100644 --- a/libwallet/src/types.rs +++ b/libwallet/src/types.rs @@ -297,6 +297,9 @@ where /// save a tx log entry fn save_tx_log_entry(&mut self, t: TxLogEntry, parent_id: &Identifier) -> Result<(), Error>; + /// delete a tx log entry + fn delete_tx_log_entry(&mut self, tx_id: u32, parent_id: &Identifier) -> Result<(), Error>; + /// save an account label -> path mapping fn save_acct_path(&mut self, mapping: AcctPathMapping) -> Result<(), Error>; diff --git a/rustfmt.toml b/rustfmt.toml index b2b2431..c691d12 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,2 +1,2 @@ hard_tabs = true -edition = "2018" +edition = "2021" diff --git a/src/bin/grin-wallet.rs b/src/bin/grin-wallet.rs index 3a192fd..9189f02 100644 --- a/src/bin/grin-wallet.rs +++ b/src/bin/grin-wallet.rs @@ -24,12 +24,12 @@ use crate::util::init_logger; use clap::App; use grin_core as core; use grin_util as util; +use grin_wallet::cmd; use grin_wallet_config as config; use grin_wallet_impls::HTTPNodeClient; use std::env; use std::path::PathBuf; - -use grin_wallet::cmd; +use std::path::MAIN_SEPARATOR; // include build information pub mod built_info { @@ -55,6 +55,13 @@ pub fn info_strings() -> (String, String) { ) } +// Helper fuction to format paths according to OS, avoids bugs on Linux +pub fn fmt_path(path: String) -> String { + let sep = &MAIN_SEPARATOR.to_string(); + let path = path.replace("/", &sep).replace("\\", &sep); + path +} + fn log_build_info() { let (basic_info, detailed_info) = info_strings(); info!("{}", basic_info); @@ -82,11 +89,11 @@ fn real_main() -> i32 { let mut current_dir = None; let mut create_path = false; - if args.is_present("top_level_dir") { let res = args.value_of("top_level_dir"); match res { Some(d) => { + let d = fmt_path(d.to_owned().to_string()); // Fix for fs to work with paths on Linux current_dir = Some(PathBuf::from(d)); } None => { @@ -138,7 +145,6 @@ fn real_main() -> i32 { "Using wallet configuration file at {}", config.config_file_path.as_ref().unwrap().to_str().unwrap() ); - log_build_info(); global::init_global_chain_type( @@ -154,9 +160,7 @@ fn real_main() -> i32 { ); global::init_global_accept_fee_base(config.members.as_ref().unwrap().wallet.accept_fee_base()); - let wallet_config = config.clone().members.unwrap().wallet; let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None).unwrap(); - cmd::wallet_command(&args, config, node_client) } diff --git a/src/cmd/wallet_args.rs b/src/cmd/wallet_args.rs index 0d6afd4..eeb5dc8 100644 --- a/src/cmd/wallet_args.rs +++ b/src/cmd/wallet_args.rs @@ -25,7 +25,7 @@ use grin_core as core; use grin_core::core::amount_to_hr_string; use grin_keychain as keychain; use grin_wallet_api::Owner; -use grin_wallet_config::{config_file_exists, TorConfig, WalletConfig}; +use grin_wallet_config::{TorConfig, WalletConfig}; use grin_wallet_controller::{command, Error}; use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl}; use grin_wallet_libwallet::{self, Slate, SlatepackAddress, SlatepackArmor}; @@ -344,7 +344,7 @@ pub fn parse_init_args( config: &WalletConfig, g_args: &command::GlobalArgs, args: &ArgMatches, - test_mode: bool, + _test_mode: bool, ) -> Result where DefaultWalletImpl<'static, C>: WalletInst<'static, L, C, K>, @@ -352,10 +352,6 @@ where C: NodeClient + 'static, K: keychain::Keychain + 'static, { - if config_file_exists(&config.data_file_dir) && !test_mode { - return Err(ParseError::WalletExists(config.data_file_dir.clone())); - } - let list_length = match args.is_present("short_wordlist") { false => 32, true => 16, @@ -1185,7 +1181,7 @@ where node_client.set_node_api_secret(global_wallet_args.node_api_secret.clone()); // legacy hack to avoid the need for changes in existing grin-wallet.toml files - // remove `wallet_data` from end of path as + // remove `wallet_data` from end of path // new lifecycle provider assumes grin_wallet.toml is in root of data directory let mut top_level_wallet_dir = PathBuf::from(wallet_config.clone().data_file_dir); if top_level_wallet_dir.ends_with(GRIN_WALLET_DIR) { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index de71fc9..2116457 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -165,7 +165,7 @@ pub fn config_command_wallet( .to_owned(), ))?; } - default_config.update_paths(¤t_dir); + default_config.update_paths(¤t_dir, ¤t_dir); default_config .write_to_file(config_file_name.to_str().unwrap(), false, None, None) .unwrap_or_else(|e| { @@ -494,4 +494,5 @@ impl From for WalletAPIReturnError { } #[derive(Clone, Debug, Serialize, Deserialize)] +#[allow(dead_code)] pub struct RetrieveSummaryInfoResp(pub bool, pub WalletInfo); diff --git a/util/Cargo.toml b/util/Cargo.toml index 879866e..ef22dde 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/mimblewimble/grin-wallet" keywords = [ "crypto", "grin", "mimblewimble" ] workspace = ".." -edition = "2018" +edition = "2021" [dependencies] rand = "0.6" @@ -21,7 +21,7 @@ thiserror = "1" ##### Grin Imports # For Release -grin_util = "5.3.3" +grin_util = "5.4.0" # For beta release