diff --git a/.changelog/unreleased/miscellaneous/493-remove-intent-gossiper.md b/.changelog/unreleased/miscellaneous/493-remove-intent-gossiper.md new file mode 100644 index 00000000000..543edeb6aac --- /dev/null +++ b/.changelog/unreleased/miscellaneous/493-remove-intent-gossiper.md @@ -0,0 +1,2 @@ +- Removed intent gossiper and matchmaker code + ([#493](https://github.com/anoma/namada/issues/493)) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42e29950d8f..c00d3f08ec8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,4 +47,4 @@ for i in $(ls -d .changelog/*/*/); do basename "$i"; done ## Development priorities -If you’d like to follow the development or contribute with new or unimplemented features, we recommend to check [the pinned issues](https://github.com/anoma/anoma/issues) that are set to tracking issues in current focus of the ledger, intent gossiper and matchmaker team. +If you’d like to follow the development or contribute with new or unimplemented features, we recommend to check [the issues](https://github.com/anoma/namada/issues) that are in current focus of the ledger team. diff --git a/Cargo.lock b/Cargo.lock index eafd05b2ff4..0874744e393 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,41 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array 0.14.5", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.2.2", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle 2.4.1", -] - [[package]] name = "ahash" version = "0.7.6" @@ -233,12 +198,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109" -[[package]] -name = "asn1_der" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" - [[package]] name = "assert_cmd" version = "1.0.8" @@ -314,7 +273,7 @@ dependencies = [ "parking", "polling", "slab", - "socket2 0.4.4", + "socket2", "waker-fn", "winapi 0.3.9", ] @@ -376,26 +335,12 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite 0.2.9", + "pin-project-lite", "pin-utils", "slab", "wasm-bindgen-futures", ] -[[package]] -name = "async-std-resolver" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf3e776afdf3a2477ef4854b85ba0dff3bd85792f685fb3c68948b4d304e4f0" -dependencies = [ - "async-std", - "async-trait", - "futures-io", - "futures-util", - "pin-utils", - "trust-dns-resolver", -] - [[package]] name = "async-stream" version = "0.3.3" @@ -443,35 +388,13 @@ dependencies = [ "futures-io", "futures-util", "log 0.4.17", - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", "tokio-rustls", - "tungstenite 0.12.0", + "tungstenite", "webpki-roots", ] -[[package]] -name = "asynchronous-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690" -dependencies = [ - "bytes 1.1.0", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite 0.2.9", -] - -[[package]] -name = "atomic" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "atomic-waker" version = "1.0.0" @@ -544,12 +467,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.13.0" @@ -611,17 +528,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "blake2" version = "0.10.4" @@ -742,7 +648,7 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", - "proc-macro-crate 0.1.5", + "proc-macro-crate", "proc-macro2", "syn", ] @@ -767,12 +673,6 @@ dependencies = [ "syn", ] -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" - [[package]] name = "bstr" version = "0.2.17" @@ -842,12 +742,6 @@ dependencies = [ "iovec", ] -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.1.0" @@ -914,18 +808,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.1.5", - "zeroize", -] - [[package]] name = "chacha20" version = "0.8.1" @@ -934,20 +816,7 @@ checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" dependencies = [ "cfg-if 1.0.0", "cipher", - "cpufeatures 0.2.2", -] - -[[package]] -name = "chacha20poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580317203210c517b6d44794abfbe600698276db18127e37ad3e69bf5e848e5" -dependencies = [ - "aead", - "chacha20 0.7.1", - "cipher", - "poly1305", - "zeroize", + "cpufeatures", ] [[package]] @@ -1135,15 +1004,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" -[[package]] -name = "cpufeatures" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.2" @@ -1292,7 +1152,7 @@ checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ "generic-array 0.14.5", "rand_core 0.6.3", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1306,16 +1166,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - [[package]] name = "crypto-mac" version = "0.8.0" @@ -1323,7 +1173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.5", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1333,7 +1183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "generic-array 0.14.5", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1361,32 +1211,12 @@ dependencies = [ "syn", ] -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher", -] - [[package]] name = "cty" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" -[[package]] -name = "cuckoofilter" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" -dependencies = [ - "byteorder", - "fnv", - "rand 0.7.3", -] - [[package]] name = "curl" version = "0.4.43" @@ -1398,7 +1228,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.4", + "socket2", "winapi 0.3.9", ] @@ -1426,7 +1256,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1512,12 +1342,6 @@ dependencies = [ "syn", ] -[[package]] -name = "data-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" - [[package]] name = "der" version = "0.5.1" @@ -1618,37 +1442,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", "crypto-common", - "subtle 2.4.1", -] - -[[package]] -name = "directories" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -dependencies = [ - "byteorder", - "quick-error 1.2.3", + "subtle", ] [[package]] @@ -1762,7 +1556,7 @@ dependencies = [ "group", "rand_core 0.6.3", "sec1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1776,7 +1570,7 @@ dependencies = [ "rustc_version 0.4.0", "toml", "vswhom", - "winreg 0.10.1", + "winreg", ] [[package]] @@ -1788,18 +1582,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "enum-as-inner" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" -dependencies = [ - "heck 0.4.0", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "enum-iterator" version = "0.7.0" @@ -1925,7 +1707,7 @@ dependencies = [ "ark-serialize", "ark-std", "bincode", - "blake2 0.10.4", + "blake2", "blake2b_simd", "borsh", "digest 0.10.3", @@ -1934,7 +1716,7 @@ dependencies = [ "ferveo-common", "group-threshold-cryptography", "hex", - "itertools 0.10.3", + "itertools", "measure_time", "miracl_core", "num", @@ -1944,7 +1726,7 @@ dependencies = [ "serde_bytes", "serde_json", "subproductdomain", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1968,7 +1750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" dependencies = [ "rand_core 0.6.3", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -2006,12 +1788,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "fixedbitset" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" - [[package]] name = "fixedbitset" version = "0.4.1" @@ -2025,7 +1801,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "libz-sys", "miniz_oxide", ] @@ -2163,7 +1938,6 @@ dependencies = [ "futures-core", "futures-task", "futures-util", - "num_cpus", ] [[package]] @@ -2183,7 +1957,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.9", + "pin-project-lite", "waker-fn", ] @@ -2198,17 +1972,6 @@ dependencies = [ "syn", ] -[[package]] -name = "futures-rustls" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1387e07917c711fb4ee4f48ea0adb04a3c9739e53ef85bf43ae1edc2937a8b" -dependencies = [ - "futures-io", - "rustls", - "webpki", -] - [[package]] name = "futures-sink" version = "0.3.21" @@ -2221,12 +1984,6 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" - [[package]] name = "futures-util" version = "0.3.21" @@ -2240,7 +1997,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite", "pin-utils", "slab", ] @@ -2286,16 +2043,6 @@ dependencies = [ "wasi 0.10.0+wasi-snapshot-preview1", ] -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug 0.3.0", - "polyval", -] - [[package]] name = "gimli" version = "0.25.0" @@ -2367,7 +2114,7 @@ checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ "ff", "rand_core 0.6.3", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -2383,9 +2130,9 @@ dependencies = [ "ark-serialize", "ark-std", "blake2b_simd", - "chacha20 0.8.1", + "chacha20", "hex", - "itertools 0.10.3", + "itertools", "miracl_core", "rand 0.8.5", "rand_core 0.6.3", @@ -2499,12 +2246,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -2520,22 +2261,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -dependencies = [ - "crypto-mac 0.7.0", - "digest 0.8.1", -] - [[package]] name = "hmac" version = "0.8.1" @@ -2556,17 +2281,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hmac-drbg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -dependencies = [ - "digest 0.8.1", - "generic-array 0.12.4", - "hmac 0.7.1", -] - [[package]] name = "hmac-drbg" version = "0.3.0" @@ -2578,17 +2292,6 @@ dependencies = [ "hmac 0.8.1", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - [[package]] name = "http" version = "0.2.8" @@ -2608,7 +2311,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes 1.1.0", "http", - "pin-project-lite 0.2.9", + "pin-project-lite", ] [[package]] @@ -2658,8 +2361,8 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.9", - "socket2 0.4.4", + "pin-project-lite", + "socket2", "tokio", "tower-service", "tracing 0.1.35", @@ -2710,7 +2413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ "hyper 0.14.19", - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", "tokio-io-timeout", ] @@ -2739,8 +2442,8 @@ dependencies = [ "ibc-proto", "ics23", "num-traits 0.2.15", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "safe-regex", "serde 1.0.137", "serde_derive", @@ -2761,8 +2464,8 @@ version = "0.16.0" source = "git+https://github.com/heliaxdev/ibc-rs?rev=30b3495ac56c6c37c99bc69ef9f2e84c3309c6cc#30b3495ac56c6c37c99bc69ef9f2e84c3309c6cc" dependencies = [ "bytes 1.1.0", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "serde 1.0.137", "tendermint-proto", "tonic", @@ -2777,7 +2480,7 @@ dependencies = [ "anyhow", "bytes 1.1.0", "hex", - "prost 0.9.0", + "prost", "ripemd160", "sha2 0.9.9", "sha3", @@ -2812,43 +2515,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "if-addrs" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2273e421f7c4f0fc99e1934fe4776f59d8df2972f4199d703fc0da9f2a9f73de" -dependencies = [ - "if-addrs-sys", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "if-addrs-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "if-watch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-lite", - "if-addrs", - "ipnet", - "libc", - "log 0.4.17", - "winapi 0.3.9", -] - [[package]] name = "indenter" version = "0.3.3" @@ -2907,12 +2573,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "integer-encoding" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e85a1509a128c855368e135cffcde7eac17d8e1083f41e2b98c58bc1a5074be" - [[package]] name = "iovec" version = "0.1.4" @@ -2923,32 +2583,11 @@ dependencies = [ ] [[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2 0.3.19", - "widestring", - "winapi 0.3.9", - "winreg 0.6.2", -] - -[[package]] -name = "ipnet" -version = "2.5.0" +name = "ipnet" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.10.3" @@ -3104,417 +2743,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "libp2p" -version = "0.38.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "atomic", - "bytes 1.1.0", - "futures 0.3.21", - "lazy_static 1.4.0", - "libp2p-core", - "libp2p-deflate", - "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-kad", - "libp2p-mdns", - "libp2p-mplex", - "libp2p-noise", - "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", - "libp2p-relay", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-swarm-derive", - "libp2p-tcp", - "libp2p-uds", - "libp2p-wasm-ext", - "libp2p-websocket", - "libp2p-yamux", - "parity-multiaddr", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "smallvec 1.8.0", - "wasm-timer", -] - -[[package]] -name = "libp2p-core" -version = "0.28.3" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "asn1_der", - "bs58", - "ed25519-dalek", - "either", - "fnv", - "futures 0.3.21", - "futures-timer", - "lazy_static 1.4.0", - "libsecp256k1 0.3.5", - "log 0.4.17", - "multihash", - "multistream-select", - "parity-multiaddr", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.7.3", - "ring", - "rw-stream-sink", - "sha2 0.9.9", - "smallvec 1.8.0", - "thiserror", - "unsigned-varint 0.7.1", - "void", - "zeroize", -] - -[[package]] -name = "libp2p-deflate" -version = "0.28.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "flate2", - "futures 0.3.21", - "libp2p-core", -] - -[[package]] -name = "libp2p-dns" -version = "0.28.1" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "async-std-resolver", - "futures 0.3.21", - "libp2p-core", - "log 0.4.17", - "smallvec 1.8.0", - "trust-dns-resolver", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.29.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "cuckoofilter", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.7.3", - "smallvec 1.8.0", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.31.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "asynchronous-codec", - "base64 0.13.0", - "byteorder", - "bytes 1.1.0", - "fnv", - "futures 0.3.21", - "hex_fmt", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.7.3", - "regex", - "sha2 0.9.9", - "smallvec 1.8.0", - "unsigned-varint 0.7.1", - "wasm-timer", -] - -[[package]] -name = "libp2p-identify" -version = "0.29.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "smallvec 1.8.0", - "wasm-timer", -] - -[[package]] -name = "libp2p-kad" -version = "0.30.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "arrayvec 0.5.2", - "asynchronous-codec", - "bytes 1.1.0", - "either", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.7.3", - "sha2 0.9.9", - "smallvec 1.8.0", - "uint", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-mdns" -version = "0.30.2" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "async-io", - "data-encoding", - "dns-parser", - "futures 0.3.21", - "if-watch", - "lazy_static 1.4.0", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "rand 0.8.5", - "smallvec 1.8.0", - "socket2 0.4.4", - "void", -] - -[[package]] -name = "libp2p-mplex" -version = "0.28.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "asynchronous-codec", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", - "log 0.4.17", - "nohash-hasher", - "parking_lot 0.11.2", - "rand 0.7.3", - "smallvec 1.8.0", - "unsigned-varint 0.7.1", -] - -[[package]] -name = "libp2p-noise" -version = "0.31.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "bytes 1.1.0", - "curve25519-dalek", - "futures 0.3.21", - "lazy_static 1.4.0", - "libp2p-core", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.8.5", - "sha2 0.9.9", - "snow", - "static_assertions", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "libp2p-ping" -version = "0.29.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "rand 0.7.3", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-plaintext" -version = "0.28.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "asynchronous-codec", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", - "log 0.4.17", - "prost 0.7.0", - "prost-build 0.7.0", - "unsigned-varint 0.7.1", - "void", -] - -[[package]] -name = "libp2p-pnet" -version = "0.21.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "futures 0.3.21", - "log 0.4.17", - "pin-project 1.0.10", - "rand 0.7.3", - "salsa20", - "sha3", -] - -[[package]] -name = "libp2p-relay" -version = "0.2.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "asynchronous-codec", - "bytes 1.1.0", - "futures 0.3.21", - "futures-timer", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "pin-project 1.0.10", - "prost 0.7.0", - "prost-build 0.7.0", - "rand 0.7.3", - "smallvec 1.8.0", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-request-response" -version = "0.11.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "async-trait", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log 0.4.17", - "lru", - "minicbor", - "rand 0.7.3", - "smallvec 1.8.0", - "unsigned-varint 0.7.1", - "wasm-timer", -] - -[[package]] -name = "libp2p-swarm" -version = "0.29.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "either", - "futures 0.3.21", - "libp2p-core", - "log 0.4.17", - "rand 0.7.3", - "smallvec 1.8.0", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.23.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "libp2p-tcp" -version = "0.28.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-timer", - "if-watch", - "ipnet", - "libc", - "libp2p-core", - "log 0.4.17", - "socket2 0.4.4", -] - -[[package]] -name = "libp2p-uds" -version = "0.28.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "async-std", - "futures 0.3.21", - "libp2p-core", - "log 0.4.17", -] - -[[package]] -name = "libp2p-wasm-ext" -version = "0.28.2" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "futures 0.3.21", - "js-sys", - "libp2p-core", - "parity-send-wrapper", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "libp2p-websocket" -version = "0.29.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "either", - "futures 0.3.21", - "futures-rustls", - "libp2p-core", - "log 0.4.17", - "quicksink", - "rw-stream-sink", - "soketto", - "url 2.2.2", - "webpki-roots", -] - -[[package]] -name = "libp2p-yamux" -version = "0.32.0" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "futures 0.3.21", - "libp2p-core", - "parking_lot 0.11.2", - "thiserror", - "yamux", -] - [[package]] name = "librocksdb-sys" version = "0.6.1+6.28.2" @@ -3530,22 +2758,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "libsecp256k1" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" -dependencies = [ - "arrayref", - "crunchy", - "digest 0.8.1", - "hmac-drbg 0.2.0", - "rand 0.7.3", - "sha2 0.8.2", - "subtle 2.4.1", - "typenum", -] - [[package]] name = "libsecp256k1" version = "0.7.0" @@ -3554,7 +2766,7 @@ dependencies = [ "arrayref", "base64 0.13.0", "digest 0.9.0", - "hmac-drbg 0.3.0", + "hmac-drbg", "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", @@ -3571,7 +2783,7 @@ source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -3685,24 +2897,6 @@ dependencies = [ "syn", ] -[[package]] -name = "lru" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea2d928b485416e8908cff2d97d621db22b27f7b3b6729e438bcf42c671ba91" -dependencies = [ - "hashbrown 0.11.2", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "mach" version = "0.3.2" @@ -3726,12 +2920,6 @@ dependencies = [ "serde_yaml", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matchers" version = "0.1.0" @@ -3799,24 +2987,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "message-io" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee18ff0c94dec5f2da5faa939b3b40122c9c38ff6d934d0917b5313ddc7b5e4" -dependencies = [ - "crossbeam-channel", - "crossbeam-utils 0.8.8", - "integer-encoding", - "lazy_static 1.4.0", - "log 0.4.17", - "mio 0.7.14", - "serde 1.0.137", - "strum", - "tungstenite 0.16.0", - "url 2.2.2", -] - [[package]] name = "mime" version = "0.2.6" @@ -3842,26 +3012,6 @@ dependencies = [ "unicase 2.6.0", ] -[[package]] -name = "minicbor" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51aa5bb0ca22415daca596a227b507f880ad1b2318a87fa9325312a5d285ca0d" -dependencies = [ - "minicbor-derive", -] - -[[package]] -name = "minicbor-derive" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54999f917cd092b13904737e26631aa2b2b88d625db68e4bab461dcd8006c788" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -3890,25 +3040,12 @@ dependencies = [ "kernel32-sys", "libc", "log 0.4.17", - "miow 0.2.2", + "miow", "net2", "slab", "winapi 0.2.8", ] -[[package]] -name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log 0.4.17", - "miow 0.3.7", - "ntapi", - "winapi 0.3.9", -] - [[package]] name = "mio" version = "0.8.3" @@ -3945,15 +3082,6 @@ dependencies = [ "ws2_32-sys", ] -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "miracl_core" version = "2.3.0" @@ -3975,52 +3103,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "multihash" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab" -dependencies = [ - "digest 0.9.0", - "generic-array 0.14.5", - "multihash-derive", - "sha2 0.9.9", - "unsigned-varint 0.5.1", -] - -[[package]] -name = "multihash-derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "multimap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "multistream-select" -version = "0.10.3" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "bytes 1.1.0", - "futures 0.3.21", - "log 0.4.17", - "pin-project 1.0.10", - "smallvec 1.8.0", - "unsigned-varint 0.7.1", -] - [[package]] name = "namada" version = "0.7.1" @@ -4043,15 +3131,15 @@ dependencies = [ "ibc", "ibc-proto", "ics23", - "itertools 0.10.3", - "libsecp256k1 0.7.0", + "itertools", + "libsecp256k1", "loupe", "namada_proof_of_stake", "parity-wasm", "pretty_assertions", "proptest", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "pwasm-utils", "rand 0.8.5", "rand_core 0.6.3", @@ -4099,7 +3187,6 @@ dependencies = [ "config", "curl", "derivative", - "directories", "ed25519-consensus", "eyre", "ferveo", @@ -4109,22 +3196,19 @@ dependencies = [ "futures 0.3.21", "git2", "hex", - "itertools 0.10.3", + "itertools", "jsonpath_lib", "libc", "libloading", - "libp2p", - "message-io", "namada", "num-derive", "num-traits 0.2.15", "num_cpus", "once_cell", "orion", - "pathdiff", "proptest", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "rand 0.8.5", "rand_core 0.6.3", "rayon", @@ -4136,7 +3220,6 @@ dependencies = [ "serde 1.0.137", "serde_bytes", "serde_json", - "serde_regex", "sha2 0.9.9", "signal-hook", "sparse-merkle-tree", @@ -4153,7 +3236,6 @@ dependencies = [ "tokio-test", "toml", "tonic", - "tonic-build", "tower", "tower-abci", "tracing 0.1.35", @@ -4168,7 +3250,7 @@ name = "namada_encoding_spec" version = "0.7.1" dependencies = [ "borsh", - "itertools 0.10.3", + "itertools", "lazy_static 1.4.0", "madato", "namada", @@ -4207,14 +3289,13 @@ dependencies = [ "file-serve", "fs_extra", "hex", - "itertools 0.10.3", - "libp2p", + "itertools", "namada", "namada_apps", "namada_vm_env", "pretty_assertions", "proptest", - "prost 0.9.0", + "prost", "rand 0.8.5", "serde_json", "sha2 0.9.9", @@ -4330,12 +3411,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - [[package]] name = "nom" version = "5.1.2" @@ -4588,7 +3663,7 @@ checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" dependencies = [ "ct-codecs", "getrandom 0.2.6", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -4613,29 +3688,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" -[[package]] -name = "parity-multiaddr" -version = "0.11.2" -source = "git+https://github.com/heliaxdev/rust-libp2p.git?rev=1abe349c231eb307d3dbe03f3ffffc6cf5e9084d#1abe349c231eb307d3dbe03f3ffffc6cf5e9084d" -dependencies = [ - "arrayref", - "bs58", - "byteorder", - "data-encoding", - "multihash", - "percent-encoding 2.1.0", - "serde 1.0.137", - "static_assertions", - "unsigned-varint 0.7.1", - "url 2.2.2", -] - -[[package]] -name = "parity-send-wrapper" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" - [[package]] name = "parity-wasm" version = "0.42.2" @@ -4659,17 +3711,6 @@ dependencies = [ "rustc_version 0.2.3", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api 0.4.7", - "parking_lot_core 0.8.5", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -4695,20 +3736,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall 0.2.13", - "smallvec 1.8.0", - "winapi 0.3.9", -] - [[package]] name = "parking_lot_core" version = "0.9.3" @@ -4728,12 +3755,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "peeking_take_while" version = "0.1.2" @@ -4788,53 +3809,23 @@ dependencies = [ "ucd-trie", ] -[[package]] -name = "petgraph" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" -dependencies = [ - "fixedbitset 0.2.0", - "indexmap", -] - [[package]] name = "petgraph" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" dependencies = [ - "fixedbitset 0.4.1", + "fixedbitset", "indexmap", ] -[[package]] -name = "pin-project" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" -dependencies = [ - "pin-project-internal 0.4.29", -] - [[package]] name = "pin-project" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" dependencies = [ - "pin-project-internal 1.0.10", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "pin-project-internal", ] [[package]] @@ -4848,12 +3839,6 @@ dependencies = [ "syn", ] -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -4885,29 +3870,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "poly1305" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" -dependencies = [ - "cpufeatures 0.2.2", - "opaque-debug 0.3.0", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.2", - "opaque-debug 0.3.0", - "universal-hash", -] - [[package]] name = "ppv-lite86" version = "0.2.16" @@ -4921,7 +3883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" dependencies = [ "difflib", - "itertools 0.10.3", + "itertools", "predicates-core", ] @@ -4962,16 +3924,6 @@ dependencies = [ "toml", ] -[[package]] -name = "proc-macro-crate" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" -dependencies = [ - "thiserror", - "toml", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -5025,41 +3977,13 @@ dependencies = [ ] [[package]] -name = "prost" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2" -dependencies = [ - "bytes 1.1.0", - "prost-derive 0.7.0", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes 1.1.0", - "prost-derive 0.9.0", -] - -[[package]] -name = "prost-build" -version = "0.7.0" +name = "prost" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d3ebd75ac2679c2af3a92246639f9fcc8a442ee420719cc4fe195b98dd5fa3" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ "bytes 1.1.0", - "heck 0.3.3", - "itertools 0.9.0", - "log 0.4.17", - "multimap", - "petgraph 0.5.1", - "prost 0.7.0", - "prost-types 0.7.0", - "tempfile", - "which", + "prost-derive", ] [[package]] @@ -5069,32 +3993,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" dependencies = [ "bytes 1.1.0", - "heck 0.3.3", - "itertools 0.10.3", + "heck", + "itertools", "lazy_static 1.4.0", "log 0.4.17", "multimap", - "petgraph 0.6.2", - "prost 0.9.0", - "prost-types 0.9.0", + "petgraph", + "prost", + "prost-types", "regex", "tempfile", "which", ] -[[package]] -name = "prost-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4" -dependencies = [ - "anyhow", - "itertools 0.9.0", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "prost-derive" version = "0.9.0" @@ -5102,22 +4013,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools 0.10.3", + "itertools", "proc-macro2", "quote", "syn", ] -[[package]] -name = "prost-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb" -dependencies = [ - "bytes 1.1.0", - "prost 0.7.0", -] - [[package]] name = "prost-types" version = "0.9.0" @@ -5125,7 +4026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" dependencies = [ "bytes 1.1.0", - "prost 0.9.0", + "prost", ] [[package]] @@ -5180,17 +4081,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quicksink" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project-lite 0.1.12", -] - [[package]] name = "quote" version = "1.0.18" @@ -5443,17 +4333,6 @@ dependencies = [ "redox_syscall 0.2.13", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.6", - "redox_syscall 0.2.13", - "thiserror", -] - [[package]] name = "regalloc" version = "0.0.31" @@ -5544,7 +4423,7 @@ dependencies = [ "mime 0.3.16", "native-tls", "percent-encoding 2.1.0", - "pin-project-lite 0.2.9", + "pin-project-lite", "serde 1.0.137", "serde_json", "serde_urlencoded", @@ -5554,17 +4433,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.10.1", -] - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error 1.2.3", + "winreg", ] [[package]] @@ -5757,17 +4626,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "rw-stream-sink" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" -dependencies = [ - "futures 0.3.21", - "pin-project 0.4.29", - "static_assertions", -] - [[package]] name = "ryu" version = "1.0.10" @@ -5827,15 +4685,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" -[[package]] -name = "salsa20" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecbd2eb639fd7cab5804a0837fe373cc2172d15437e804c054a9fb885cb923b0" -dependencies = [ - "cipher", -] - [[package]] name = "same-file" version = "1.0.6" @@ -5885,7 +4734,7 @@ checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", "generic-array 0.14.5", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -6010,16 +4859,6 @@ dependencies = [ "serde 1.0.137", ] -[[package]] -name = "serde_regex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" -dependencies = [ - "regex", - "serde 1.0.137", -] - [[package]] name = "serde_repr" version = "0.1.8" @@ -6084,7 +4923,7 @@ checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -6096,22 +4935,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cpufeatures", "digest 0.10.3", ] -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.9" @@ -6120,7 +4947,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -6132,7 +4959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cpufeatures", "digest 0.10.3", ] @@ -6225,35 +5052,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" -[[package]] -name = "snow" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6142f7c25e94f6fd25a32c3348ec230df9109b463f59c8c7acc4bd34936babb7" -dependencies = [ - "aes-gcm", - "blake2 0.9.2", - "chacha20poly1305", - "rand 0.8.5", - "rand_core 0.6.3", - "ring", - "rustc_version 0.3.3", - "sha2 0.9.9", - "subtle 2.4.1", - "x25519-dalek", -] - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - [[package]] name = "socket2" version = "0.4.4" @@ -6264,22 +5062,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "soketto" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c71ed3d54db0a699f4948e1bb3e45b450fa31fe602621dee6680361d569c88" -dependencies = [ - "base64 0.12.3", - "bytes 0.5.6", - "flate2", - "futures 0.3.21", - "httparse", - "log 0.4.17", - "rand 0.7.3", - "sha-1 0.9.8", -] - [[package]] name = "sp-std" version = "3.0.0" @@ -6341,28 +5123,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strum" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" -dependencies = [ - "heck 0.4.0", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "subproductdomain" version = "0.1.0" @@ -6376,12 +5136,6 @@ dependencies = [ "ark-std", ] -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.1" @@ -6485,8 +5239,8 @@ dependencies = [ "k256", "num-traits 0.2.15", "once_cell", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "ripemd160", "serde 1.0.137", "serde_bytes", @@ -6494,7 +5248,7 @@ dependencies = [ "serde_repr", "sha2 0.9.9", "signature", - "subtle 2.4.1", + "subtle", "subtle-encoding", "tendermint-proto", "time 0.3.9", @@ -6536,8 +5290,8 @@ dependencies = [ "flex-error", "num-derive", "num-traits 0.2.15", - "prost 0.9.0", - "prost-types 0.9.0", + "prost", + "prost-types", "serde 1.0.137", "serde_bytes", "subtle-encoding", @@ -6560,7 +5314,7 @@ dependencies = [ "hyper-proxy", "hyper-rustls", "peg", - "pin-project 1.0.10", + "pin-project", "serde 1.0.137", "serde_bytes", "serde_json", @@ -6768,9 +5522,9 @@ dependencies = [ "num_cpus", "once_cell", "parking_lot 0.12.1", - "pin-project-lite 0.2.9", + "pin-project-lite", "signal-hook-registry", - "socket2 0.4.4", + "socket2", "tokio-macros", "winapi 0.3.9", ] @@ -6813,7 +5567,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", ] @@ -6875,7 +5629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" dependencies = [ "futures-core", - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", ] @@ -6937,7 +5691,7 @@ dependencies = [ "futures-core", "futures-sink", "log 0.4.17", - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", ] @@ -6950,7 +5704,7 @@ dependencies = [ "bytes 1.1.0", "futures-core", "futures-sink", - "pin-project-lite 0.2.9", + "pin-project-lite", "tokio", "tracing 0.1.35", ] @@ -6982,9 +5736,9 @@ dependencies = [ "hyper 0.14.19", "hyper-timeout", "percent-encoding 2.1.0", - "pin-project 1.0.10", - "prost 0.9.0", - "prost-derive 0.9.0", + "pin-project", + "prost", + "prost-derive", "tokio", "tokio-stream", "tokio-util 0.6.10", @@ -7002,7 +5756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757" dependencies = [ "proc-macro2", - "prost-build 0.9.0", + "prost-build", "quote", "syn", ] @@ -7017,8 +5771,8 @@ dependencies = [ "futures-util", "hdrhistogram", "indexmap", - "pin-project 1.0.10", - "pin-project-lite 0.2.9", + "pin-project", + "pin-project-lite", "rand 0.8.5", "slab", "tokio", @@ -7035,8 +5789,8 @@ source = "git+https://github.com/heliaxdev/tower-abci?rev=f6463388fc319b6e210503 dependencies = [ "bytes 1.1.0", "futures 0.3.21", - "pin-project 1.0.10", - "prost 0.9.0", + "pin-project", + "prost", "tendermint-proto", "tokio", "tokio-stream", @@ -7073,7 +5827,7 @@ version = "0.1.30" source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d857db8ba1b553f7b293ac8ba967a42f8" dependencies = [ "cfg-if 1.0.0", - "pin-project-lite 0.2.9", + "pin-project-lite", "tracing-attributes 0.1.19", "tracing-core 0.1.22", ] @@ -7086,7 +5840,7 @@ checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ "cfg-if 1.0.0", "log 0.4.17", - "pin-project-lite 0.2.9", + "pin-project-lite", "tracing-attributes 0.1.21", "tracing-core 0.1.27", ] @@ -7146,7 +5900,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.10", + "pin-project", "tracing 0.1.35", ] @@ -7155,7 +5909,7 @@ name = "tracing-futures" version = "0.2.5" source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d857db8ba1b553f7b293ac8ba967a42f8" dependencies = [ - "pin-project-lite 0.2.9", + "pin-project-lite", "tracing 0.1.30", ] @@ -7205,7 +5959,7 @@ version = "0.1.0" source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d857db8ba1b553f7b293ac8ba967a42f8" dependencies = [ "futures 0.3.21", - "pin-project-lite 0.2.9", + "pin-project-lite", "tower-layer", "tower-make", "tower-service", @@ -7219,49 +5973,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -[[package]] -name = "trust-dns-proto" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static 1.4.0", - "log 0.4.17", - "rand 0.8.5", - "smallvec 1.8.0", - "thiserror", - "tinyvec", - "url 2.2.2", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a" -dependencies = [ - "cfg-if 1.0.0", - "futures-util", - "ipconfig", - "lazy_static 1.4.0", - "log 0.4.17", - "lru-cache", - "parking_lot 0.11.2", - "resolv-conf", - "smallvec 1.8.0", - "thiserror", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.3" @@ -7287,25 +5998,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tungstenite" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" -dependencies = [ - "base64 0.13.0", - "byteorder", - "bytes 1.1.0", - "http", - "httparse", - "log 0.4.17", - "rand 0.8.5", - "sha-1 0.9.8", - "thiserror", - "url 2.2.2", - "utf-8", -] - [[package]] name = "typeable" version = "0.1.2" @@ -7324,18 +6016,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicase" version = "1.4.2" @@ -7393,16 +6073,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array 0.14.5", - "subtle 2.4.1", -] - [[package]] name = "unreachable" version = "1.0.0" @@ -7412,24 +6082,6 @@ dependencies = [ "void", ] -[[package]] -name = "unsigned-varint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" - -[[package]] -name = "unsigned-varint" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" -dependencies = [ - "asynchronous-codec", - "bytes 1.1.0", - "futures-io", - "futures-util", -] - [[package]] name = "untrusted" version = "0.7.1" @@ -7675,21 +6327,6 @@ dependencies = [ "leb128", ] -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" -dependencies = [ - "futures 0.3.21", - "js-sys", - "parking_lot 0.11.2", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasmer" version = "2.2.0" @@ -8057,12 +6694,6 @@ dependencies = [ "libc", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "winapi" version = "0.2.8" @@ -8192,15 +6823,6 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winreg" version = "0.10.1" @@ -8220,17 +6842,6 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "x25519-dalek" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" -dependencies = [ - "curve25519-dalek", - "rand_core 0.5.1", - "zeroize", -] - [[package]] name = "xattr" version = "0.2.3" @@ -8249,20 +6860,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "yamux" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107" -dependencies = [ - "futures 0.3.21", - "log 0.4.17", - "nohash-hasher", - "parking_lot 0.11.2", - "rand 0.8.5", - "static_assertions", -] - [[package]] name = "zeroize" version = "1.5.5" diff --git a/Cargo.toml b/Cargo.toml index 2bb0d8ad104..0acc6646da0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,8 +20,6 @@ exclude = [ ] [patch.crates-io] -# TODO backported patch in the noise protocl for , blocked on libp2p upgrade -libp2p = {git = "https://github.com/heliaxdev/rust-libp2p.git", rev = "1abe349c231eb307d3dbe03f3ffffc6cf5e9084d"} # TODO temp patch for , and more tba. borsh = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} borsh-derive = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} diff --git a/Makefile b/Makefile index 6bcb62c75f1..0330a569e7d 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,7 @@ build-wasm-image-docker: build-wasm-scripts-docker: build-wasm-image-docker docker run --rm -v ${PWD}:/__w/namada/namada namada-wasm make build-wasm-scripts -# Build the validity predicate, transactions, matchmaker and matchmaker filter wasm +# Build the validity predicate and transactions wasm build-wasm-scripts: make -C $(wasms) make opt-wasm diff --git a/README.md b/README.md index 323bc5e9b86..b93113ea5d0 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ interaction with the protocol. ## 📓 Docs -- user docs: built from [docs mdBook](./documentation/docs/) -- dev docs: built from [dev mdBook](./documentation/dev/) -- specifications: built from [specs mdBook](./documentation/specs/) +* user docs: built from [docs mdBook](./documentation/docs/) +* dev docs: built from [dev mdBook](./documentation/dev/) +* specifications: built from [specs mdBook](./documentation/specs/) ## Warning @@ -47,7 +47,7 @@ Guide. ## ⚙️ Development ```shell -# Build the provided validity predicate, transaction and matchmaker wasm modules +# Build the provided validity predicate and transaction wasm modules make build-wasm-scripts-docker # Development (debug) build Anoma, which includes a validator and some default @@ -69,11 +69,11 @@ make clippy To change the log level, set `ANOMA_LOG` environment variable to one of: -- `error` -- `warn` -- `info` -- `debug` -- `trace` +* `error` +* `warn` +* `info` +* `debug` +* `trace` The default is set to `info` for all the modules, expect for Tendermint ABCI, which has a lot of `debug` logging. diff --git a/apps/Cargo.toml b/apps/Cargo.toml index 65d7d84eed0..23a27a65fce 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -63,7 +63,6 @@ color-eyre = "0.5.10" config = "0.11.0" curl = "0.4.43" derivative = "2.2.0" -directories = "4.0.1" ed25519-consensus = "1.2.0" ferveo = {git = "https://github.com/anoma/ferveo"} ferveo-common = {git = "https://github.com/anoma/ferveo"} @@ -76,14 +75,11 @@ itertools = "0.10.1" jsonpath_lib = "0.3.0" libc = "0.2.97" libloading = "0.7.2" -libp2p = "0.38.0" -message-io = {version = "0.14.3", default-features = false, features = ["websocket"]} num-derive = "0.3.3" num-traits = "0.2.14" num_cpus = "1.13.0" once_cell = "1.8.0" orion = "0.16.0" -pathdiff = "0.2.1" prost = "0.9.0" prost-types = "0.9.0" rand = {version = "0.8", default-features = false} @@ -97,7 +93,6 @@ rpassword = "5.0.1" serde = {version = "1.0.125", features = ["derive"]} serde_bytes = "0.11.5" serde_json = {version = "1.0.62", features = ["raw_value"]} -serde_regex = "1.1.0" sha2 = "0.9.3" signal-hook = "0.3.9" sparse-merkle-tree = {git = "https://github.com/heliaxdev/sparse-merkle-tree", branch = "yuji/prost-0.9", features = ["borsh"]} @@ -135,4 +130,3 @@ tokio-test = "0.4.2" [build-dependencies] git2 = "0.13.25" -tonic-build = "0.6.0" diff --git a/apps/build.rs b/apps/build.rs index ae49503e78e..32f7c57e875 100644 --- a/apps/build.rs +++ b/apps/build.rs @@ -1,6 +1,5 @@ -use std::fs::{read_to_string, File}; +use std::fs::File; use std::io::Write; -use std::process::Command; use std::{env, str}; use git2::{DescribeFormatOptions, DescribeOptions, Repository}; @@ -8,9 +7,6 @@ use git2::{DescribeFormatOptions, DescribeOptions, Repository}; /// Path to the .proto source files, relative to `apps` directory const PROTO_SRC: &str = "./proto"; -/// The version should match the one we use in the `Makefile` -const RUSTFMT_TOOLCHAIN_SRC: &str = "../rust-nightly-version"; - fn main() { // Discover the repository version, if it exists println!("cargo:rerun-if-changed=../.git"); @@ -66,43 +62,4 @@ fn main() { println!("cargo:rustc-cfg=feature=\"dev\""); } } - - let mut use_rustfmt = false; - - // The version should match the one we use in the `Makefile` - if let Ok(rustfmt_toolchain) = read_to_string(RUSTFMT_TOOLCHAIN_SRC) { - // Try to find the path to rustfmt. - if let Ok(output) = Command::new("rustup") - .args(&[ - "which", - "rustfmt", - "--toolchain", - rustfmt_toolchain.trim(), - ]) - .output() - { - if let Ok(rustfmt) = str::from_utf8(&output.stdout) { - // Set the command to be used by tonic_build below to format the - // generated files - let rustfmt = rustfmt.trim(); - if !rustfmt.is_empty() { - println!("using rustfmt from path \"{}\"", rustfmt); - env::set_var("RUSTFMT", rustfmt); - use_rustfmt = true - } - } - } - } - - tonic_build::configure() - .out_dir("src/lib/proto/generated") - .format(use_rustfmt) - .extern_path(".types", "::namada::proto::generated::types") - // This warning appears in tonic generated code - .server_mod_attribute(".", "#[allow(clippy::unit_arg)]") - // TODO try to add json encoding to simplify use for user - // .type_attribute("types.Intent", "#[derive(serde::Serialize, - // serde::Deserialize)]") - .compile(&[format!("{}/services.proto", PROTO_SRC)], &[PROTO_SRC]) - .unwrap(); } diff --git a/apps/src/bin/anoma-client/cli.rs b/apps/src/bin/anoma-client/cli.rs index d04eeff9abd..1da669e8ae4 100644 --- a/apps/src/bin/anoma-client/cli.rs +++ b/apps/src/bin/anoma-client/cli.rs @@ -3,7 +3,7 @@ use color_eyre::eyre::Result; use namada_apps::cli; use namada_apps::cli::cmds::*; -use namada_apps::client::{gossip, rpc, tx, utils}; +use namada_apps::client::{rpc, tx, utils}; pub async fn main() -> Result<()> { match cli::anoma_client_cli() { @@ -80,13 +80,6 @@ pub async fn main() -> Result<()> { Sub::QueryProtocolParameters(QueryProtocolParameters(args)) => { rpc::query_protocol_parameters(ctx, args).await; } - // Gossip cmds - Sub::Intent(Intent(args)) => { - gossip::gossip_intent(ctx, args).await; - } - Sub::SubscribeTopic(SubscribeTopic(args)) => { - gossip::subscribe_topic(ctx, args).await; - } } } cli::AnomaClient::WithoutContext(cmd, global_args) => match cmd { diff --git a/apps/src/bin/anoma-node/cli.rs b/apps/src/bin/anoma-node/cli.rs index 407a6b7378d..65ed7d59bf2 100644 --- a/apps/src/bin/anoma-node/cli.rs +++ b/apps/src/bin/anoma-node/cli.rs @@ -1,8 +1,8 @@ //! Anoma node CLI. use eyre::{Context, Result}; -use namada_apps::cli::{self, args, cmds}; -use namada_apps::node::{gossip, ledger, matchmaker}; +use namada_apps::cli::{self, cmds}; +use namada_apps::node::ledger; pub fn main() -> Result<()> { let (cmd, mut ctx) = cli::anoma_node_cli(); @@ -20,55 +20,6 @@ pub fn main() -> Result<()> { .wrap_err("Failed to reset Anoma node")?; } }, - cmds::AnomaNode::Gossip(sub) => match sub { - cmds::Gossip::Run(cmds::GossipRun(args::GossipRun { - addr, - rpc, - })) => { - let config = ctx.config; - let mut gossip_cfg = config.intent_gossiper; - gossip_cfg.update(addr, rpc); - gossip::run( - gossip_cfg, - &config - .ledger - .shell - .base_dir - .join(ctx.global_config.default_chain_id.as_str()), - ) - .wrap_err("Failed to run gossip service")?; - } - }, - cmds::AnomaNode::Matchmaker(cmds::Matchmaker(args::Matchmaker { - intent_gossiper_addr, - matchmaker_path, - tx_code_path, - ledger_addr, - tx_signing_key, - tx_source_address, - })) => { - let tx_signing_key = ctx.get_cached(&tx_signing_key); - let tx_source_address = ctx.get(&tx_source_address); - - let wasm_dir = ctx.wasm_dir(); - let config = ctx.config; - let mut mm_config = config.matchmaker; - if matchmaker_path.is_some() { - mm_config.matchmaker_path = matchmaker_path; - } - if tx_code_path.is_some() { - mm_config.tx_code_path = tx_code_path; - } - - matchmaker::run( - mm_config, - intent_gossiper_addr, - ledger_addr, - tx_signing_key, - tx_source_address, - wasm_dir, - ); - } cmds::AnomaNode::Config(sub) => match sub { cmds::Config::Gen(cmds::ConfigGen) => { // If the config doesn't exit, it gets generated in the context. diff --git a/apps/src/bin/anoma/cli.rs b/apps/src/bin/anoma/cli.rs index b0ed783276c..ccde0c36185 100644 --- a/apps/src/bin/anoma/cli.rs +++ b/apps/src/bin/anoma/cli.rs @@ -39,10 +39,7 @@ fn handle_command(cmd: cli::cmds::Anoma, raw_sub_cmd: String) -> Result<()> { } match cmd { - cli::cmds::Anoma::Node(_) - | cli::cmds::Anoma::Ledger(_) - | cli::cmds::Anoma::Gossip(_) - | cli::cmds::Anoma::Matchmaker(_) => { + cli::cmds::Anoma::Node(_) | cli::cmds::Anoma::Ledger(_) => { handle_subcommand("namadan", sub_args) } cli::cmds::Anoma::Client(_) @@ -52,8 +49,9 @@ fn handle_command(cmd: cli::cmds::Anoma, raw_sub_cmd: String) -> Result<()> { | cli::cmds::Anoma::TxInitNft(_) | cli::cmds::Anoma::TxMintNft(_) | cli::cmds::Anoma::TxInitProposal(_) - | cli::cmds::Anoma::TxVoteProposal(_) - | cli::cmds::Anoma::Intent(_) => handle_subcommand("namadac", sub_args), + | cli::cmds::Anoma::TxVoteProposal(_) => { + handle_subcommand("namadac", sub_args) + } cli::cmds::Anoma::Wallet(_) => handle_subcommand("namadaw", sub_args), } } diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs index f546860cfde..1b014cc21b2 100644 --- a/apps/src/lib/cli.rs +++ b/apps/src/lib/cli.rs @@ -41,8 +41,6 @@ pub mod cmds { // Inlined commands from the node. Ledger(Ledger), - Gossip(Gossip), - Matchmaker(Matchmaker), // Inlined commands from the client. TxCustom(TxCustom), @@ -52,7 +50,6 @@ pub mod cmds { TxMintNft(TxMintNft), TxInitProposal(TxInitProposal), TxVoteProposal(TxVoteProposal), - Intent(Intent), } impl Cmd for Anoma { @@ -61,8 +58,6 @@ pub mod cmds { .subcommand(AnomaClient::def()) .subcommand(AnomaWallet::def()) .subcommand(Ledger::def()) - .subcommand(Gossip::def()) - .subcommand(Matchmaker::def()) .subcommand(TxCustom::def()) .subcommand(TxTransfer::def()) .subcommand(TxUpdateVp::def()) @@ -70,7 +65,6 @@ pub mod cmds { .subcommand(TxMintNft::def()) .subcommand(TxInitProposal::def()) .subcommand(TxVoteProposal::def()) - .subcommand(Intent::def()) } fn parse(matches: &ArgMatches) -> Option { @@ -78,8 +72,6 @@ pub mod cmds { let client = SubCmd::parse(matches).map(Self::Client); let wallet = SubCmd::parse(matches).map(Self::Wallet); let ledger = SubCmd::parse(matches).map(Self::Ledger); - let gossip = SubCmd::parse(matches).map(Self::Gossip); - let matchmaker = SubCmd::parse(matches).map(Self::Matchmaker); let tx_custom = SubCmd::parse(matches).map(Self::TxCustom); let tx_transfer = SubCmd::parse(matches).map(Self::TxTransfer); let tx_update_vp = SubCmd::parse(matches).map(Self::TxUpdateVp); @@ -89,12 +81,9 @@ pub mod cmds { SubCmd::parse(matches).map(Self::TxInitProposal); let tx_vote_proposal = SubCmd::parse(matches).map(Self::TxVoteProposal); - let intent = SubCmd::parse(matches).map(Self::Intent); node.or(client) .or(wallet) .or(ledger) - .or(gossip) - .or(matchmaker) .or(tx_custom) .or(tx_transfer) .or(tx_update_vp) @@ -102,7 +91,6 @@ pub mod cmds { .or(tx_nft_mint) .or(tx_init_proposal) .or(tx_vote_proposal) - .or(intent) } } @@ -112,25 +100,18 @@ pub mod cmds { #[allow(clippy::large_enum_variant)] pub enum AnomaNode { Ledger(Ledger), - Gossip(Gossip), - Matchmaker(Matchmaker), Config(Config), } impl Cmd for AnomaNode { fn add_sub(app: App) -> App { - app.subcommand(Ledger::def()) - .subcommand(Gossip::def()) - .subcommand(Matchmaker::def()) - .subcommand(Config::def()) + app.subcommand(Ledger::def()).subcommand(Config::def()) } fn parse(matches: &ArgMatches) -> Option { let ledger = SubCmd::parse(matches).map(Self::Ledger); - let gossip = SubCmd::parse(matches).map(Self::Gossip); - let matchmaker = SubCmd::parse(matches).map(Self::Matchmaker); let config = SubCmd::parse(matches).map(Self::Config); - ledger.or(gossip).or(matchmaker).or(config) + ledger.or(config) } } impl SubCmd for AnomaNode { @@ -194,9 +175,6 @@ pub mod cmds { .subcommand(QueryProposal::def().display_order(3)) .subcommand(QueryProposalResult::def().display_order(3)) .subcommand(QueryProtocolParameters::def().display_order(3)) - // Intents - .subcommand(Intent::def().display_order(4)) - .subcommand(SubscribeTopic::def().display_order(4)) // Utils .subcommand(Utils::def().display_order(5)) } @@ -231,8 +209,6 @@ pub mod cmds { Self::parse_with_ctx(matches, QueryProposalResult); let query_protocol_parameters = Self::parse_with_ctx(matches, QueryProtocolParameters); - let intent = Self::parse_with_ctx(matches, Intent); - let subscribe_topic = Self::parse_with_ctx(matches, SubscribeTopic); let utils = SubCmd::parse(matches).map(Self::WithoutContext); tx_custom .or(tx_transfer) @@ -256,8 +232,6 @@ pub mod cmds { .or(query_proposal) .or(query_proposal_result) .or(query_protocol_parameters) - .or(intent) - .or(subscribe_topic) .or(utils) } } @@ -316,9 +290,6 @@ pub mod cmds { QueryProposal(QueryProposal), QueryProposalResult(QueryProposalResult), QueryProtocolParameters(QueryProtocolParameters), - // Gossip cmds - Intent(Intent), - SubscribeTopic(SubscribeTopic), } #[derive(Clone, Debug)] @@ -657,76 +628,6 @@ pub mod cmds { } } - #[derive(Clone, Debug)] - pub enum Gossip { - Run(GossipRun), - } - - impl SubCmd for Gossip { - const CMD: &'static str = "gossip"; - - fn parse(matches: &ArgMatches) -> Option { - matches.subcommand_matches(Self::CMD).and_then(|matches| { - let run = SubCmd::parse(matches).map(Gossip::Run); - run - // The `run` command is the default if no sub-command given - .or_else(|| { - Some(Gossip::Run(GossipRun(args::GossipRun::parse( - matches, - )))) - }) - }) - } - - fn def() -> App { - App::new(Self::CMD) - .about( - "Gossip node sub-commands. If no sub-command specified, \ - defaults to run the node.", - ) - .subcommand(GossipRun::def()) - .add_args::() - } - } - - #[derive(Clone, Debug)] - pub struct Matchmaker(pub args::Matchmaker); - - impl SubCmd for Matchmaker { - const CMD: &'static str = "matchmaker"; - - fn parse(matches: &ArgMatches) -> Option { - matches - .subcommand_matches(Self::CMD) - .map(|matches| Matchmaker(args::Matchmaker::parse(matches))) - } - - fn def() -> App { - App::new(Self::CMD) - .about("Run a matchmaker.") - .add_args::() - } - } - - #[derive(Clone, Debug)] - pub struct GossipRun(pub args::GossipRun); - - impl SubCmd for GossipRun { - const CMD: &'static str = "run"; - - fn parse(matches: &ArgMatches) -> Option { - matches - .subcommand_matches(Self::CMD) - .map(|matches| GossipRun(args::GossipRun::parse(matches))) - } - - fn def() -> App { - App::new(Self::CMD) - .about("Run a gossip node.") - .add_args::() - } - } - #[derive(Clone, Debug)] pub enum Config { Gen(ConfigGen), @@ -1218,47 +1119,6 @@ pub mod cmds { } } - #[derive(Clone, Debug)] - pub struct Intent(pub args::Intent); - - impl SubCmd for Intent { - const CMD: &'static str = "intent"; - - fn parse(matches: &ArgMatches) -> Option { - matches - .subcommand_matches(Self::CMD) - .map(|matches| Intent(args::Intent::parse(matches))) - } - - fn def() -> App { - App::new(Self::CMD) - .about("Send an intent.") - .add_args::() - } - } - - #[derive(Clone, Debug)] - pub struct SubscribeTopic(pub args::SubscribeTopic); - - impl SubCmd for SubscribeTopic { - const CMD: &'static str = "subscribe-topic"; - - fn parse(matches: &ArgMatches) -> Option { - matches.subcommand_matches(Self::CMD).map(|matches| { - SubscribeTopic(args::SubscribeTopic::parse(matches)) - }) - } - - fn def() -> App { - App::new(Self::CMD) - .about( - "Subscribe intent gossip node with a matchmaker to a \ - topic.", - ) - .add_args::() - } - } - #[derive(Clone, Debug)] pub enum Utils { JoinNetwork(JoinNetwork), @@ -1355,23 +1215,18 @@ pub mod cmds { pub mod args { - use std::convert::TryFrom; use std::env; - use std::fs::File; use std::net::SocketAddr; use std::path::PathBuf; use std::str::FromStr; - use libp2p::Multiaddr; use namada::types::address::Address; use namada::types::chain::{ChainId, ChainIdPrefix}; use namada::types::governance::ProposalVote; - use namada::types::intent::{DecimalWrapper, Exchange}; use namada::types::key::*; use namada::types::storage::{self, Epoch}; use namada::types::token; use namada::types::transaction::GasLimit; - use serde::Deserialize; use tendermint::Timeout; use tendermint_config::net::Address as TendermintAddress; @@ -1419,13 +1274,6 @@ pub mod args { arg_default("gas-limit", DefaultFn(|| token::Amount::from(0))); const GENESIS_PATH: Arg = arg("genesis-path"); const GENESIS_VALIDATOR: ArgOpt = arg("genesis-validator").opt(); - const INTENT_GOSSIPER_ADDR: ArgDefault = arg_default( - "intent-gossiper", - DefaultFn(|| { - let raw = "127.0.0.1:26661"; - SocketAddr::from_str(raw).unwrap() - }), - ); const LEDGER_ADDRESS_ABOUT: &str = "Address of a ledger node as \"{scheme}://{host}:{port}\". If the \ scheme is not supplied, it is assumed to be TCP."; @@ -1437,12 +1285,8 @@ pub mod args { const LEDGER_ADDRESS: Arg = arg("ledger-address"); const LOCALHOST: ArgFlag = flag("localhost"); - const MATCHMAKER_PATH: ArgOpt = arg_opt("matchmaker-path"); const MODE: ArgOpt = arg_opt("mode"); - const MULTIADDR_OPT: ArgOpt = arg_opt("address"); const NET_ADDRESS: Arg = arg("net-address"); - const NODE_OPT: ArgOpt = arg_opt("node"); - const NODE: Arg = arg("node"); const NFT_ADDRESS: Arg
= arg("nft-address"); const OWNER: ArgOpt = arg_opt("owner"); const PROPOSAL_OFFLINE: ArgFlag = flag("offline"); @@ -1456,7 +1300,6 @@ pub mod args { const RAW_PUBLIC_KEY_OPT: ArgOpt = arg_opt("public-key"); const REWARDS_CODE_PATH: ArgOpt = arg_opt("rewards-code-path"); const REWARDS_KEY: ArgOpt = arg_opt("rewards-key"); - const RPC_SOCKET_ADDR: ArgOpt = arg_opt("rpc"); const SCHEME: ArgDefault = arg_default("scheme", DefaultFn(|| SchemeType::Ed25519)); const SIGNER: ArgOpt = arg_opt("signer"); @@ -1466,12 +1309,8 @@ pub mod args { const SOURCE_OPT: ArgOpt = SOURCE.opt(); const STORAGE_KEY: Arg = arg("storage-key"); const TARGET: Arg = arg("target"); - const TO_STDOUT: ArgFlag = flag("stdout"); const TOKEN_OPT: ArgOpt = TOKEN.opt(); const TOKEN: Arg = arg("token"); - const TOPIC_OPT: ArgOpt = arg_opt("topic"); - const TOPIC: Arg = arg("topic"); - const TX_CODE_PATH: ArgOpt = arg_opt("tx-code-path"); const TX_HASH: Arg = arg("tx-hash"); const UNSAFE_DONT_ENCRYPT: ArgFlag = flag("unsafe-dont-encrypt"); const UNSAFE_SHOW_SECRET: ArgFlag = flag("unsafe-show-secret"); @@ -1523,11 +1362,11 @@ pub mod args { )) .arg(WASM_DIR.def().about( "Directory with built WASM validity predicates, \ - transactions and matchmaker files. This must not be an \ - absolute path as the directory is nested inside the \ - chain directory. This value can also be set via \ - `ANOMA_WASM_DIR` environment variable, but the argument \ - takes precedence, if specified.", + transactions. This must not be an absolute path as the \ + directory is nested inside the chain directory. This \ + value can also be set via `ANOMA_WASM_DIR` environment \ + variable, but the argument takes precedence, if \ + specified.", )) .arg(MODE.def().about( "The mode in which to run Anoma. Options are \n\t * \ @@ -2214,67 +2053,6 @@ pub mod args { } } - /// Helper struct for generating intents - #[derive(Debug, Clone, Deserialize)] - pub struct ExchangeDefinition { - /// The source address - pub addr: String, - /// The token to be sold - pub token_sell: String, - /// The minimum rate - pub rate_min: String, - /// The maximum amount of token to be sold - pub max_sell: String, - /// The token to be bought - pub token_buy: String, - /// The amount of token to be bought - pub min_buy: String, - /// The path to the wasm vp code - pub vp_path: Option, - } - - impl TryFrom for Exchange { - type Error = &'static str; - - fn try_from( - value: ExchangeDefinition, - ) -> Result { - let vp = if let Some(path) = value.vp_path { - if let Ok(wasm) = std::fs::read(path.clone()) { - Some(wasm) - } else { - eprintln!("File {} was not found.", path); - None - } - } else { - None - }; - - let addr = Address::decode(value.addr) - .expect("Addr should be a valid address"); - let token_buy = Address::decode(value.token_buy) - .expect("Token_buy should be a valid address"); - let token_sell = Address::decode(value.token_sell) - .expect("Token_sell should be a valid address"); - let min_buy = token::Amount::from_str(&value.min_buy) - .expect("Min_buy must be convertible to number"); - let max_sell = token::Amount::from_str(&value.max_sell) - .expect("Max_sell must be convertible to number"); - let rate_min = DecimalWrapper::from_str(&value.rate_min) - .expect("Max_sell must be convertible to decimal."); - - Ok(Exchange { - addr, - token_sell, - rate_min, - max_sell, - token_buy, - min_buy, - vp, - }) - } - } - /// Query PoS bond(s) #[derive(Clone, Debug)] pub struct QueryBonds { @@ -2393,218 +2171,6 @@ pub mod args { .arg(STORAGE_KEY.def().about("Storage key")) } } - /// Intent arguments - #[derive(Clone, Debug)] - pub struct Intent { - /// Gossip node address - pub node_addr: Option, - /// Intent topic - pub topic: Option, - /// Source address - pub source: Option, - /// Signing key - pub signing_key: Option, - /// Exchanges description - pub exchanges: Vec, - /// The address of the ledger node as host:port - pub ledger_address: TendermintAddress, - /// Print output to stdout - pub to_stdout: bool, - } - - impl Args for Intent { - fn parse(matches: &ArgMatches) -> Self { - let node_addr = NODE_OPT.parse(matches); - let data_path = DATA_PATH.parse(matches); - let source = SOURCE_OPT.parse(matches); - let signing_key = SIGNING_KEY_OPT.parse(matches); - let to_stdout = TO_STDOUT.parse(matches); - let topic = TOPIC_OPT.parse(matches); - - let file = File::open(&data_path).expect("File must exist."); - let exchange_definitions: Vec = - serde_json::from_reader(file) - .expect("JSON was not well-formatted"); - - let exchanges: Vec = exchange_definitions - .iter() - .map(|item| { - Exchange::try_from(item.clone()).expect( - "Conversion from ExchangeDefinition to Exchange \ - should not fail.", - ) - }) - .collect(); - let ledger_address = LEDGER_ADDRESS_DEFAULT.parse(matches); - - Self { - node_addr, - topic, - source, - signing_key, - exchanges, - ledger_address, - to_stdout, - } - } - - fn def(app: App) -> App { - app.arg( - NODE_OPT - .def() - .about("The gossip node address.") - .conflicts_with(TO_STDOUT.name), - ) - .arg(DATA_PATH.def().about( - "The data of the intent, that contains all value necessary \ - for the matchmaker.", - )) - .arg( - SOURCE_OPT - .def() - .about( - "Sign the intent with the key of a given address or \ - address alias from your wallet.", - ) - .conflicts_with(SIGNING_KEY_OPT.name), - ) - .arg( - SIGNING_KEY_OPT - .def() - .about( - "Sign the intent with the key for the given public \ - key, public key hash or alias from your wallet.", - ) - .conflicts_with(SOURCE_OPT.name), - ) - .arg(LEDGER_ADDRESS_DEFAULT.def().about(LEDGER_ADDRESS_ABOUT)) - .arg( - TOPIC_OPT - .def() - .about("The subnetwork where the intent should be sent to.") - .conflicts_with(TO_STDOUT.name), - ) - .arg( - TO_STDOUT - .def() - .about( - "Echo the serialized intent to stdout. Note that with \ - this option, the intent won't be submitted to the \ - intent gossiper RPC.", - ) - .conflicts_with_all(&[NODE_OPT.name, TOPIC.name]), - ) - } - } - - /// Subscribe intent topic arguments - #[derive(Clone, Debug)] - pub struct SubscribeTopic { - /// Gossip node address - pub node_addr: String, - /// Intent topic - pub topic: String, - } - - impl Args for SubscribeTopic { - fn parse(matches: &ArgMatches) -> Self { - let node_addr = NODE.parse(matches); - let topic = TOPIC.parse(matches); - Self { node_addr, topic } - } - - fn def(app: App) -> App { - app.arg(NODE.def().about("The gossip node address.")).arg( - TOPIC - .def() - .about("The new topic of interest for that node."), - ) - } - } - - #[derive(Clone, Debug)] - pub struct GossipRun { - pub addr: Option, - pub rpc: Option, - } - - impl Args for GossipRun { - fn parse(matches: &ArgMatches) -> Self { - let addr = MULTIADDR_OPT.parse(matches); - let rpc = RPC_SOCKET_ADDR.parse(matches); - Self { addr, rpc } - } - - fn def(app: App) -> App { - app.arg( - MULTIADDR_OPT - .def() - .about("Gossip service address as host:port."), - ) - .arg(RPC_SOCKET_ADDR.def().about("Enable RPC service.")) - } - } - - #[derive(Clone, Debug)] - pub struct Matchmaker { - pub matchmaker_path: Option, - pub tx_code_path: Option, - pub intent_gossiper_addr: SocketAddr, - pub ledger_addr: TendermintAddress, - pub tx_signing_key: WalletKeypair, - pub tx_source_address: WalletAddress, - } - - impl Args for Matchmaker { - fn parse(matches: &ArgMatches) -> Self { - let intent_gossiper_addr = INTENT_GOSSIPER_ADDR.parse(matches); - let matchmaker_path = MATCHMAKER_PATH.parse(matches); - let tx_code_path = TX_CODE_PATH.parse(matches); - let ledger_addr = LEDGER_ADDRESS_DEFAULT.parse(matches); - let tx_signing_key = SIGNING_KEY.parse(matches); - let tx_source_address = SOURCE.parse(matches); - Self { - intent_gossiper_addr, - matchmaker_path, - tx_code_path, - ledger_addr, - tx_signing_key, - tx_source_address, - } - } - - fn def(app: App) -> App { - app.arg(INTENT_GOSSIPER_ADDR.def().about( - "Intent Gossiper endpoint for matchmaker connections as \ - \"{host}:{port}\".", - )) - .arg(MATCHMAKER_PATH.def().about( - "The file name of the matchmaker compiled to a dynamic \ - library (the filename extension is optional).", - )) - .arg( - TX_CODE_PATH - .def() - .about("The transaction code to use with the matchmaker."), - ) - .arg(LEDGER_ADDRESS_DEFAULT.def().about( - "The address of the ledger as \"{scheme}://{host}:{port}\" \ - that the matchmaker must send transactions to. If the scheme \ - is not supplied, it is assumed to be TCP.", - )) - .arg(SIGNING_KEY.def().about( - "Sign the transactions created by the matchmaker with the key \ - for the given public key, public key hash or alias from your \ - wallet.", - )) - .arg(SOURCE.def().about( - "Source address or alias of an address of the transactions \ - created by the matchmaker. This must be matching the signing \ - key.", - )) - } - } - /// Common transaction arguments #[derive(Clone, Debug)] pub struct Tx { @@ -3004,7 +2570,7 @@ pub mod args { )) .arg(LOCALHOST.def().about( "Use localhost address for P2P and RPC connections for the \ - validators ledger and intent gossip nodes", + validators ledger", )) .arg(ALLOW_DUPLICATE_IP.def().about( "Toggle to disable guard against peers connecting from the \ diff --git a/apps/src/lib/cli/context.rs b/apps/src/lib/cli/context.rs index 8189b633bfc..ca5daff8fe3 100644 --- a/apps/src/lib/cli/context.rs +++ b/apps/src/lib/cli/context.rs @@ -44,7 +44,7 @@ pub struct Context { pub wallet: Wallet, /// The global configuration pub global_config: GlobalConfig, - /// The ledger & intent gossip configuration for a specific chain ID + /// The ledger configuration for a specific chain ID pub config: Config, } diff --git a/apps/src/lib/client/gossip.rs b/apps/src/lib/client/gossip.rs deleted file mode 100644 index 2225898ff4d..00000000000 --- a/apps/src/lib/client/gossip.rs +++ /dev/null @@ -1,116 +0,0 @@ -use std::collections::HashSet; -use std::io::Write; - -use borsh::BorshSerialize; -use namada::proto::Signed; -use namada::types::intent::{Exchange, FungibleTokenIntent}; -use tendermint_config::net::Address as TendermintAddress; - -use super::signing; -use crate::cli::{self, args, Context}; -use crate::proto::services::rpc_service_client::RpcServiceClient; -use crate::proto::{services, RpcMessage}; -use crate::wallet::Wallet; - -/// Create an intent, sign it and submit it to the gossip node (unless -/// `to_stdout` is `true`). -pub async fn gossip_intent( - mut ctx: Context, - args::Intent { - node_addr, - topic, - source, - signing_key, - exchanges, - ledger_address, - to_stdout, - }: args::Intent, -) { - let mut signed_exchanges: HashSet> = - HashSet::with_capacity(exchanges.len()); - for exchange in exchanges { - let signed = - sign_exchange(&mut ctx.wallet, exchange, ledger_address.clone()) - .await; - signed_exchanges.insert(signed); - } - - let source_keypair = match ctx.get_opt_cached(&signing_key) { - Some(key) => key, - None => { - let source = ctx.get_opt(&source).unwrap_or_else(|| { - eprintln!("A source or a signing key is required."); - cli::safe_exit(1) - }); - signing::find_keypair( - &mut ctx.wallet, - &source, - ledger_address.clone(), - ) - .await - } - }; - let signed_ft: Signed = Signed::new( - &*source_keypair, - FungibleTokenIntent { - exchange: signed_exchanges, - }, - ); - let data_bytes = signed_ft.try_to_vec().unwrap(); - - if to_stdout { - let mut out = std::io::stdout(); - out.write_all(&data_bytes).unwrap(); - out.flush().unwrap(); - } else { - let node_addr = node_addr.expect( - "Gossip node address must be defined to submit the intent to it.", - ); - let topic = topic.expect( - "The topic must be defined to submit the intent to a gossip node.", - ); - - match RpcServiceClient::connect(node_addr.clone()).await { - Ok(mut client) => { - let intent = namada::proto::Intent::new(data_bytes); - let message: services::RpcMessage = - RpcMessage::new_intent(intent, topic).into(); - let response = client.send_message(message).await.expect( - "Failed to send message and/or receive rpc response", - ); - println!("{:#?}", response); - } - Err(e) => { - eprintln!( - "Error connecting RPC client to {}: {}", - node_addr, e - ); - } - }; - } -} - -/// Request an intent gossip node with a matchmaker to subscribe to a given -/// topic. -pub async fn subscribe_topic( - _ctx: Context, - args::SubscribeTopic { node_addr, topic }: args::SubscribeTopic, -) { - let mut client = RpcServiceClient::connect(node_addr).await.unwrap(); - let message: services::RpcMessage = RpcMessage::new_topic(topic).into(); - let response = client - .send_message(message) - .await - .expect("failed to send message and/or receive rpc response"); - println!("{:#?}", response); -} - -async fn sign_exchange( - wallet: &mut Wallet, - exchange: Exchange, - ledger_address: TendermintAddress, -) -> Signed { - let source_keypair = - signing::find_keypair(wallet, &exchange.addr, ledger_address).await; - Signed::new(&*source_keypair, exchange.clone()) -} diff --git a/apps/src/lib/client/mod.rs b/apps/src/lib/client/mod.rs index a3d2ddece9f..e27e575ce08 100644 --- a/apps/src/lib/client/mod.rs +++ b/apps/src/lib/client/mod.rs @@ -1,4 +1,3 @@ -pub mod gossip; pub mod rpc; pub mod signing; pub mod tendermint_rpc_types; diff --git a/apps/src/lib/client/utils.rs b/apps/src/lib/client/utils.rs index 9043a14db73..d2d49341fe2 100644 --- a/apps/src/lib/client/utils.rs +++ b/apps/src/lib/client/utils.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::env; use std::fs::{self, File, OpenOptions}; use std::io::Write; @@ -27,10 +27,7 @@ use crate::config::genesis::genesis_config::{ self, HexString, ValidatorPreGenesisConfig, }; use crate::config::global::GlobalConfig; -use crate::config::{ - self, Config, IntentGossiper, PeerAddress, TendermintMode, -}; -use crate::node::gossip; +use crate::config::{self, Config, TendermintMode}; use crate::node::ledger::tendermint_node; use crate::wallet::{pre_genesis, Wallet}; use crate::wasm_loader; @@ -422,25 +419,10 @@ pub fn init_network( let mut rng: ThreadRng = thread_rng(); + // Accumulator of validators' Tendermint P2P addresses let mut persistent_peers: Vec = Vec::with_capacity(config.validator.len()); - // Intent gossiper config bootstrap peers where we'll add the address for - // each validator's node - let mut seed_peers: HashSet = - HashSet::with_capacity(config.validator.len()); - let mut gossiper_configs: HashMap = - HashMap::with_capacity(config.validator.len()); - let mut matchmaker_configs: HashMap = - HashMap::with_capacity(config.validator.len()); - // Other accounts owned by one of the validators - let mut validator_owned_accounts: HashMap< - String, - genesis_config::EstablishedAccountConfig, - > = HashMap::default(); - - // We need a temporary copy to be able to use this inside the validator - // loop, which has mutable borrow on the config. - let established_accounts = config.established.clone(); + // Iterate over each validator, generating keys and addresses config.validator.iter_mut().for_each(|(name, config)| { let validator_dir = accounts_dir.join(name); @@ -477,36 +459,6 @@ pub fn init_network( )) .expect("Validator address must be valid"); persistent_peers.push(peer); - // Add a Intent gossiper bootstrap peer from the validator's IP - let mut gossiper_config = IntentGossiper::default(); - // Generate P2P identity - let p2p_identity = gossip::p2p::Identity::gen(&chain_dir); - let peer_id = p2p_identity.peer_id(); - let ledger_addr = - SocketAddr::from_str(config.net_address.as_ref().unwrap()).unwrap(); - let ip = ledger_addr.ip().to_string(); - let first_port = ledger_addr.port(); - let intent_peer_address = libp2p::Multiaddr::from_str( - format!("/ip4/{}/tcp/{}", ip, first_port + 3).as_str(), - ) - .unwrap(); - - gossiper_config.address = if localhost { - intent_peer_address.clone() - } else { - libp2p::Multiaddr::from_str( - format!("/ip4/0.0.0.0/tcp/{}", first_port + 3).as_str(), - ) - .unwrap() - }; - if let Some(discover) = gossiper_config.discover_peer.as_mut() { - // Disable mDNS local network peer discovery on the validator nodes - discover.mdns = false; - } - let intent_peer = PeerAddress { - address: intent_peer_address, - peer_id, - }; // Generate account and reward addresses let address = address::gen_established_address("validator account"); @@ -634,93 +586,20 @@ pub fn init_network( wallet.add_address(name.clone(), address); wallet.add_address(format!("{}-reward", &name), reward_address); - // Check if there's a matchmaker configured for this validator node - match ( - &config.matchmaker_account, - &config.matchmaker_code, - &config.matchmaker_tx, - ) { - (Some(account), Some(mm_code), Some(tx_code)) => { - if config.intent_gossip_seed.unwrap_or_default() { - eprintln!("A bootstrap node cannot run matchmakers"); - cli::safe_exit(1) - } - match established_accounts.as_ref().and_then(|e| e.get(account)) - { - Some(matchmaker) => { - let mut matchmaker = matchmaker.clone(); - - init_established_account( - account, - &mut wallet, - &mut matchmaker, - unsafe_dont_encrypt, - ); - validator_owned_accounts - .insert(account.clone(), matchmaker); - - let matchmaker_config = config::Matchmaker { - matchmaker_path: Some(mm_code.clone().into()), - tx_code_path: Some(tx_code.clone().into()), - }; - matchmaker_configs - .insert(name.clone(), matchmaker_config); - } - None => { - eprintln!( - "Misconfigured validator's matchmaker. No \ - established account with alias {} found", - account - ); - cli::safe_exit(1) - } - } - } - (None, None, None) => {} - _ => { - eprintln!( - "Misconfigured validator's matchmaker. \ - `matchmaker_account`, `matchmaker_code` and \ - `matchmaker_tx` must be all or none present." - ); - cli::safe_exit(1) - } - } - - // Store the gossip config - gossiper_configs.insert(name.clone(), gossiper_config); - if config.intent_gossip_seed.unwrap_or_default() { - seed_peers.insert(intent_peer); - } - wallet.save().unwrap(); }); - if seed_peers.is_empty() && config.validator.len() > 1 { - tracing::warn!( - "At least 1 validator with `intent_gossip_seed = true` is needed \ - to established connection between the intent gossiper nodes" - ); - } - // Create a wallet for all accounts other than validators let mut wallet = Wallet::load_or_new(&accounts_dir.join(NET_OTHER_ACCOUNTS_DIR)); if let Some(established) = &mut config.established { established.iter_mut().for_each(|(name, config)| { - match validator_owned_accounts.get(name) { - Some(validator_owned) => { - *config = validator_owned.clone(); - } - None => { - init_established_account( - name, - &mut wallet, - config, - unsafe_dont_encrypt, - ); - } - } + init_established_account( + name, + &mut wallet, + config, + unsafe_dont_encrypt, + ); }) } @@ -857,7 +736,7 @@ pub fn init_network( wallet.save().unwrap(); }); - // Generate the validators' ledger and intent gossip config + // Generate the validators' ledger config config.validator.iter_mut().enumerate().for_each( |(ix, (name, validator_config))| { let accounts_dir = chain_dir.join(NET_ACCOUNTS_DIR); @@ -920,26 +799,6 @@ pub fn init_network( // Validator node should turned off peer exchange reactor config.ledger.tendermint.p2p_pex = false; - // Configure the intent gossiper, matchmaker (if any) and RPC - config.intent_gossiper = gossiper_configs.remove(name).unwrap(); - config.intent_gossiper.seed_peers = seed_peers.clone(); - config.matchmaker = - matchmaker_configs.remove(name).unwrap_or_default(); - config.intent_gossiper.rpc = Some(config::RpcServer { - address: SocketAddr::new( - IpAddr::V4(if localhost { - Ipv4Addr::new(127, 0, 0, 1) - } else { - Ipv4Addr::new(0, 0, 0, 0) - }), - first_port + 4, - ), - }); - config - .intent_gossiper - .matchmakers_server_addr - .set_port(first_port + 5); - config.write(&validator_dir, &chain_id, true).unwrap(); }, ); @@ -960,7 +819,6 @@ pub fn init_network( } config.ledger.tendermint.p2p_addr_book_strict = !localhost; config.ledger.genesis_time = genesis.genesis_time.into(); - config.intent_gossiper.seed_peers = seed_peers; config .write(&global_args.base_dir, &chain_id, true) .unwrap(); diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index 5bd3dc803f2..4462c62960a 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -189,16 +189,6 @@ pub mod genesis_config { pub staking_reward_vp: Option, // IP:port of the validator. (used in generation only) pub net_address: Option, - /// Matchmaker account's alias, if any - pub matchmaker_account: Option, - /// Path to a matchmaker WASM program, if any - pub matchmaker_code: Option, - /// Path to a transaction WASM code used by the matchmaker, if any - pub matchmaker_tx: Option, - /// Is this validator running a seed intent gossip node? A seed node is - /// not part of the gossipsub where intents are being propagated and - /// hence cannot run matchmakers - pub intent_gossip_seed: Option, /// Tendermint node key is used to derive Tendermint node ID for node /// authentication pub tendermint_node_key: Option, @@ -803,13 +793,6 @@ pub fn genesis() -> Genesis { public_key: Some(wallet::defaults::christel_keypair().ref_to()), storage: HashMap::default(), }; - let matchmaker = EstablishedAccount { - address: wallet::defaults::matchmaker_address(), - vp_code_path: vp_user_path.into(), - vp_sha256: Default::default(), - public_key: Some(wallet::defaults::matchmaker_keypair().ref_to()), - storage: HashMap::default(), - }; let implicit_accounts = vec![ImplicitAccount { public_key: wallet::defaults::daewon_keypair().ref_to(), }]; @@ -836,10 +819,6 @@ pub fn genesis() -> Genesis { default_key_tokens, ), ((&validator.account_key).into(), default_key_tokens), - ( - matchmaker.public_key.as_ref().unwrap().into(), - default_key_tokens, - ), ]); let token_accounts = address::tokens() .into_iter() @@ -853,7 +832,7 @@ pub fn genesis() -> Genesis { Genesis { genesis_time: DateTimeUtc::now(), validators: vec![validator], - established_accounts: vec![albert, bertha, christel, matchmaker], + established_accounts: vec![albert, bertha, christel], implicit_accounts, token_accounts, parameters, diff --git a/apps/src/lib/config/mod.rs b/apps/src/lib/config/mod.rs index 987077d5cda..17b9529684c 100644 --- a/apps/src/lib/config/mod.rs +++ b/apps/src/lib/config/mod.rs @@ -4,21 +4,15 @@ pub mod genesis; pub mod global; pub mod utils; -use std::collections::HashSet; -use std::fmt::Display; use std::fs::{create_dir_all, File}; use std::io::Write; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::str::FromStr; -use libp2p::multiaddr::{Multiaddr, Protocol}; -use libp2p::multihash::Multihash; -use libp2p::PeerId; use namada::types::chain::ChainId; use namada::types::time::Rfc3339String; -use regex::Regex; -use serde::{de, Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use tendermint::Timeout; use tendermint_config::net::Address as TendermintAddress; use thiserror::Error; @@ -43,9 +37,6 @@ pub const DB_DIR: &str = "db"; pub struct Config { pub wasm_dir: PathBuf, pub ledger: Ledger, - pub intent_gossiper: IntentGossiper, - // TODO allow to configure multiple matchmakers - pub matchmaker: Matchmaker, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -126,32 +117,6 @@ pub struct Tendermint { pub instrumentation_namespace: String, } -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct IntentGossiper { - // Simple values - pub address: Multiaddr, - pub topics: HashSet, - /// The server address to which matchmakers can connect to receive intents - pub matchmakers_server_addr: SocketAddr, - - // Nested structures ⚠️ no simple values below any of these ⚠️ - pub subscription_filter: SubscriptionFilter, - pub seed_peers: HashSet, - pub rpc: Option, - pub discover_peer: Option, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct RpcServer { - pub address: SocketAddr, -} - -#[derive(Default, Debug, Serialize, Deserialize, Clone)] -pub struct Matchmaker { - pub matchmaker_path: Option, - pub tx_code_path: Option, -} - impl Ledger { pub fn new( base_dir: impl AsRef, @@ -228,38 +193,6 @@ impl Shell { } } -// TODO maybe add also maxCount for a maximum number of subscription for a -// filter. - -// TODO toml failed to serialize without "untagged" because does not support -// enum with nested data, unless with the untagged flag. This might be a source -// of confusion in the future... Another approach would be to have multiple -// field for each filter possibility but it's less nice. -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(untagged)] -pub enum SubscriptionFilter { - RegexFilter(#[serde(with = "serde_regex")] Regex), - WhitelistFilter(Vec), -} - -// TODO peer_id can be part of Multiaddr, mayby this splitting is not useful ? -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] -pub struct PeerAddress { - pub address: Multiaddr, - pub peer_id: PeerId, -} - -// TODO add reserved_peers: explicit peers for gossipsub network, to not be -// added to kademlia -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct DiscoverPeer { - pub max_discovery_peers: u64, - /// Toggle Kademlia remote peer discovery, on by default - pub kademlia: bool, - /// Toggle local network mDNS peer discovery, off by default - pub mdns: bool, -} - #[derive(Error, Debug)] pub enum Error { #[error("Error while reading config: {0}")] @@ -302,8 +235,6 @@ impl Config { Self { wasm_dir: DEFAULT_WASM_DIR.into(), ledger: Ledger::new(base_dir, chain_id, mode), - intent_gossiper: IntentGossiper::default(), - matchmaker: Matchmaker::default(), } } @@ -412,97 +343,6 @@ impl Config { } } -impl Default for IntentGossiper { - fn default() -> Self { - Self { - address: Multiaddr::from_str("/ip4/0.0.0.0/tcp/26659").unwrap(), - topics: vec!["asset_v0"].into_iter().map(String::from).collect(), - matchmakers_server_addr: SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - 26661, - ), - subscription_filter: SubscriptionFilter::RegexFilter( - Regex::new("asset_v\\d{1,2}").unwrap(), - ), - seed_peers: HashSet::default(), - rpc: None, - discover_peer: Some(DiscoverPeer::default()), - } - } -} - -impl IntentGossiper { - pub fn update(&mut self, addr: Option, rpc: Option) { - if let Some(addr) = addr { - self.address = addr; - } - if let Some(address) = rpc { - self.rpc = Some(RpcServer { address }); - } - } -} - -impl Default for RpcServer { - fn default() -> Self { - Self { - address: SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - 26660, - ), - } - } -} - -impl Serialize for PeerAddress { - fn serialize( - &self, - serializer: S, - ) -> std::result::Result - where - S: serde::Serializer, - { - let mut address = self.address.clone(); - address.push(Protocol::P2p(Multihash::from(self.peer_id))); - address.serialize(serializer) - } -} - -impl de::Error for SerdeError { - fn custom(msg: T) -> Self { - SerdeError::Message(msg.to_string()) - } -} - -impl<'de> Deserialize<'de> for PeerAddress { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - - let mut address = Multiaddr::deserialize(deserializer) - .map_err(|err| SerdeError::BadBootstrapPeerFormat(err.to_string())) - .map_err(D::Error::custom)?; - if let Some(Protocol::P2p(mh)) = address.pop() { - let peer_id = PeerId::from_multihash(mh).unwrap(); - Ok(Self { address, peer_id }) - } else { - Err(SerdeError::BadBootstrapPeerFormat(address.to_string())) - .map_err(D::Error::custom) - } - } -} - -impl Default for DiscoverPeer { - fn default() -> Self { - Self { - max_discovery_peers: 16, - kademlia: true, - mdns: false, - } - } -} - pub const VALUE_AFTER_TABLE_ERROR_MSG: &str = r#" Error while serializing to toml. It means that some nested structure is followed by simple fields. diff --git a/apps/src/lib/mod.rs b/apps/src/lib/mod.rs index eca89896ebb..b0455934bd5 100644 --- a/apps/src/lib/mod.rs +++ b/apps/src/lib/mod.rs @@ -10,7 +10,6 @@ pub mod client; pub mod config; pub mod logging; pub mod node; -pub mod proto; pub mod wallet; pub mod wasm_loader; diff --git a/apps/src/lib/node/gossip/intent_gossiper.rs b/apps/src/lib/node/gossip/intent_gossiper.rs deleted file mode 100644 index 2c7816a5bf8..00000000000 --- a/apps/src/lib/node/gossip/intent_gossiper.rs +++ /dev/null @@ -1,123 +0,0 @@ -use std::net::ToSocketAddrs; -use std::sync::{Arc, RwLock}; - -use namada::proto::{Intent, IntentId}; - -use super::mempool::IntentMempool; -use super::rpc::matchmakers::{ - MsgFromClient, MsgFromServer, ServerDialer, ServerListener, -}; - -/// A server for connected matchmakers that can receive intents from the intent -/// gossiper node and send back the results from their filter, if any, or from -/// trying to match them. -#[derive(Debug, Default)] -pub struct MatchmakersServer { - /// A node listener and its abort receiver. These are consumed once the - /// listener is started with [`MatchmakersServer::listen`]. - listener: Option, - /// Known intents mempool, shared with [`IntentGossiper`]. - mempool: Arc>, -} - -/// Intent gossiper handle can be cloned and is thread safe. -#[derive(Clone, Debug)] -pub struct IntentGossiper { - /// Known intents mempool, shared with [`MatchmakersServer`]. - mempool: Arc>, - /// A dialer can send messages to the connected matchmaker - dialer: ServerDialer, -} - -impl MatchmakersServer { - /// Create a new gossip intent app with a matchmaker, if enabled. - pub fn new_pair( - matchmakers_server_addr: impl ToSocketAddrs, - ) -> (Self, IntentGossiper) { - // Prepare a server for matchmakers connections - let (listener, dialer) = - ServerListener::new_pair(matchmakers_server_addr); - - let mempool = Arc::new(RwLock::new(IntentMempool::default())); - let intent_gossiper = IntentGossiper { - mempool: mempool.clone(), - dialer, - }; - ( - Self { - listener: Some(listener), - mempool, - }, - intent_gossiper, - ) - } - - pub async fn listen(mut self) { - self.listener - .take() - .unwrap() - .listen(|msg| match msg { - MsgFromClient::InvalidIntent { id } => { - let id = IntentId(id); - // Remove matched intents from mempool - tracing::info!("Removing matched intent ID {}", id); - let mut w_mempool = self.mempool.write().unwrap(); - w_mempool.remove(&id); - } - MsgFromClient::IntentConstraintsTooComplex { id } => { - let id = IntentId(id); - tracing::info!( - "Intent ID {} has constraints that are too complex \ - for a connected matchmaker", - id - ); - } - MsgFromClient::IgnoredIntent { id } => { - let id = IntentId(id); - tracing::info!( - "Intent ID {} ignored by a connected matchmaker", - id - ); - } - MsgFromClient::Matched { intent_ids } => { - // Remove matched intents from mempool - let mut w_mempool = self.mempool.write().unwrap(); - for id in intent_ids { - let id = IntentId(id); - tracing::info!("Removing matched intent ID {}", id); - w_mempool.remove(&id); - } - } - MsgFromClient::Unmatched { id } => { - let id = IntentId(id); - tracing::info!("No match found for intent ID {}", id); - } - }) - .await - } -} - -impl IntentGossiper { - // Apply the logic to a new intent. It only tries to apply the matchmaker if - // this one exists. If no matchmaker then returns true. - pub async fn add_intent(&mut self, intent: Intent) { - let id = intent.id(); - - let r_mempool = self.mempool.read().unwrap(); - let is_known = r_mempool.contains(&id); - drop(r_mempool); - if !is_known { - let mut w_mempool = self.mempool.write().unwrap(); - w_mempool.insert(intent.clone()); - } - - tracing::info!( - "Sending intent ID {} to connected matchmakers, if any", - id - ); - self.dialer.send(MsgFromServer::AddIntent { - id: id.0, - data: intent.data, - }) - } -} diff --git a/apps/src/lib/node/gossip/mempool.rs b/apps/src/lib/node/gossip/mempool.rs deleted file mode 100644 index fce66447c44..00000000000 --- a/apps/src/lib/node/gossip/mempool.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::collections::HashMap; - -use namada::proto::{Intent, IntentId}; - -/// In-memory intent mempool -#[derive(Clone, Debug, Default)] -pub struct IntentMempool(HashMap); - -impl IntentMempool { - /// Insert a new intent. If the mempool didn't have this intent present, - /// returns `true`. - pub fn insert(&mut self, intent: Intent) -> bool { - self.0.insert(intent.id(), intent).is_none() - } - - /// Remove an intent from mempool. If the mempool didn't have this intent - /// present, returns `true`. in the mempool. - pub fn remove(&mut self, intent_id: &IntentId) -> bool { - self.0.remove(intent_id).is_some() - } - - /// Returns `true` if the map contains intent with specified ID. - pub fn contains(&self, intent_id: &IntentId) -> bool { - self.0.contains_key(intent_id) - } -} diff --git a/apps/src/lib/node/gossip/mod.rs b/apps/src/lib/node/gossip/mod.rs deleted file mode 100644 index 03b14f14efa..00000000000 --- a/apps/src/lib/node/gossip/mod.rs +++ /dev/null @@ -1,116 +0,0 @@ -pub mod intent_gossiper; -mod mempool; -pub mod p2p; -pub mod rpc; - -use std::path::Path; - -use namada::proto::Intent; -use thiserror::Error; -use tokio::sync::mpsc; - -use self::intent_gossiper::IntentGossiper; -use self::p2p::P2P; -use crate::config; -use crate::proto::services::{rpc_message, RpcResponse}; - -#[derive(Error, Debug)] -pub enum Error { - #[error("Error initializing p2p: {0}")] - P2pInit(p2p::Error), -} - -type Result = std::result::Result; - -/// RPC async receiver end of the channel -pub type RpcReceiver = tokio::sync::mpsc::Receiver<( - rpc_message::Message, - tokio::sync::oneshot::Sender, -)>; - -#[tokio::main] -pub async fn run( - config: config::IntentGossiper, - base_dir: impl AsRef, -) -> Result<()> { - // Prepare matchmakers server and dialer - let (matchmakers_server, intent_gossiper) = - intent_gossiper::MatchmakersServer::new_pair( - &config.matchmakers_server_addr, - ); - - // Async channel for intents received from peer - let (peer_intent_send, peer_intent_recv) = tokio::sync::mpsc::channel(100); - - // Create the P2P gossip network, which can send messages directly to the - // matchmaker, if any - let p2p = p2p::P2P::new(&config, base_dir, peer_intent_send) - .await - .map_err(Error::P2pInit)?; - - // Run the matchmakers server - let mms_join_handle = tokio::task::spawn(async move { - matchmakers_server.listen().await; - }); - - // Start the RPC server, if enabled in the config - let rpc_receiver = config.rpc.map(|rpc_config| { - let (rpc_sender, rpc_receiver) = mpsc::channel(100); - tokio::spawn(async move { - rpc::client::start_rpc_server(&rpc_config, rpc_sender).await - }); - rpc_receiver - }); - - dispatcher( - p2p, - rpc_receiver, - peer_intent_recv, - intent_gossiper, - mms_join_handle, - ) - .await -} - -// loop over all possible event. The event can be from the rpc, a matchmaker -// program or the gossip network. The gossip network event are a special case -// that does not need to be handle as it's taking care of by the libp2p internal -// logic. -pub async fn dispatcher( - mut p2p: P2P, - mut rpc_receiver: Option, - mut peer_intent_recv: tokio::sync::mpsc::Receiver, - mut intent_gossiper: IntentGossiper, - _mms_join_handle: tokio::task::JoinHandle<()>, -) -> Result<()> { - loop { - tokio::select! { - Some((event, inject_response)) = recv_rpc_option(rpc_receiver.as_mut()), if rpc_receiver.is_some() => - { - let gossip_sub = &mut p2p.0.behaviour_mut().intent_gossip_behaviour; - let (response, maybe_intent) = rpc::client::handle_rpc_event(event, gossip_sub).await; - inject_response.send(response).expect("failed to send response to rpc server"); - - if let Some(intent) = maybe_intent { - intent_gossiper.add_intent(intent).await; - } - }, - Some(intent) = peer_intent_recv.recv() => { - intent_gossiper.add_intent(intent).await; - } - swarm_event = p2p.0.next() => { - // Never occurs, but call for the event must exists. - tracing::info!("event, {:?}", swarm_event); - }, - }; - } -} - -async fn recv_rpc_option( - x: Option<&mut RpcReceiver>, -) -> Option<( - rpc_message::Message, - tokio::sync::oneshot::Sender, -)> { - x?.recv().await -} diff --git a/apps/src/lib/node/gossip/p2p/behaviour/discovery.rs b/apps/src/lib/node/gossip/p2p/behaviour/discovery.rs deleted file mode 100644 index 57d99c7bc03..00000000000 --- a/apps/src/lib/node/gossip/p2p/behaviour/discovery.rs +++ /dev/null @@ -1,517 +0,0 @@ -// This file is almost identical to this -// https://github.com/webb-tools/anonima/blob/main/network/src/discovery.rs -// appropriate affiliation needs to be added here original header : -// -// Copyright 2020 ChainSafe Systems SPDX-License-Identifier: Apache-2.0, MIT - -use std::collections::{HashSet, VecDeque}; -use std::fmt::Display; -use std::task::{Context, Poll}; -use std::time::Duration; -use std::{cmp, io}; - -use async_std::stream::{self, Interval}; -use futures::StreamExt; -use libp2p::core::connection::{ConnectionId, ListenerId}; -use libp2p::core::ConnectedPoint; -use libp2p::kad::handler::KademliaHandlerProto; -use libp2p::kad::store::MemoryStore; -use libp2p::kad::{Kademlia, KademliaConfig, KademliaEvent, QueryId}; -use libp2p::mdns::{Mdns, MdnsConfig, MdnsEvent}; -use libp2p::swarm::toggle::{Toggle, ToggleIntoProtoHandler}; -use libp2p::swarm::{ - IntoProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, ProtocolsHandler, -}; -use libp2p::{Multiaddr, PeerId}; -use thiserror::Error; - -use crate::config::PeerAddress; - -#[derive(Error, Debug)] -pub enum Error { - // TODO, it seems that NoKnownPeer is not exposed, could not find it - #[error("Failed to bootstrap kademlia {0}")] - FailedBootstrap(String), - #[error("Failed to initialize mdns {0}")] - FailedMdns(std::io::Error), -} - -pub type Result = std::result::Result; - -/// Event generated by the `DiscoveryBehaviour`. -#[derive(Debug)] -pub enum DiscoveryEvent { - /// Event that notifies that we connected to the node with the given peer - /// id. - Connected(PeerId), - - /// Event that notifies that we disconnected with the node with the given - /// peer id. - Disconnected(PeerId), - - /// This case is only use to clean the code in the poll fct - KademliaEvent(KademliaEvent), -} - -/// `DiscoveryBehaviour` configuration. -#[derive(Clone)] -pub struct DiscoveryConfig { - /// user defined peer that are given to kad in order to connect to the - /// network - user_defined: Vec, - /// maximum number of peer to connect to - discovery_max: u64, - /// enable kademlia to find new peer - enable_kademlia: bool, - /// look for new peer over local network. - // TODO: it seems that kademlia must activated where it should not be - // mandatory - enable_mdns: bool, - // TODO: should this be optional? if not explain why - /// use the option from kademlia. Prevent some type of attacks against - /// kademlia. - kademlia_disjoint_query_paths: bool, -} - -impl Default for DiscoveryConfig { - fn default() -> Self { - Self { - user_defined: Vec::new(), - discovery_max: u64::MAX, - enable_kademlia: true, - enable_mdns: true, - kademlia_disjoint_query_paths: true, - } - } -} - -#[derive(Default)] -pub struct DiscoveryConfigBuilder { - config: DiscoveryConfig, -} - -impl DiscoveryConfigBuilder { - /// Set the number of active connections at which we pause discovery. - pub fn discovery_limit(&mut self, limit: u64) -> &mut Self { - self.config.discovery_max = limit; - self - } - - /// Set custom nodes which never expire, e.g. bootstrap or reserved nodes. - pub fn with_user_defined(&mut self, user_defined: I) -> &mut Self - where - I: IntoIterator, - { - self.config.user_defined.extend(user_defined); - self - } - - /// Configures if disjoint query path is enabled - pub fn use_kademlia_disjoint_query_paths( - &mut self, - value: bool, - ) -> &mut Self { - self.config.kademlia_disjoint_query_paths = value; - self - } - - /// Configures if mdns is enabled. - pub fn with_mdns(&mut self, value: bool) -> &mut Self { - self.config.enable_mdns = value; - self - } - - /// Configures if Kademlia is enabled. - pub fn with_kademlia(&mut self, value: bool) -> &mut Self { - self.config.enable_kademlia = value; - self - } - - /// Build the discovery config - pub fn build(&self) -> Result { - Ok(self.config.clone()) - } -} - -/// Implementation of `NetworkBehaviour` that discovers the nodes on the -/// network. -pub struct DiscoveryBehaviour { - /// User-defined list of nodes and their addresses. Typically includes - /// bootstrap nodes and reserved nodes. - user_defined: Vec, - /// Kademlia discovery. - pub kademlia: Toggle>, - /// Discovers nodes on the local network. - mdns: Toggle, - /// Stream that fires when we need to perform the next random Kademlia - /// query. - next_kad_random_query: Option, - /// After `next_kad_random_query` triggers, the next one triggers after - /// this duration. - duration_to_next_kad: Duration, - /// Events to return in priority when polled. - pending_events: VecDeque, - /// Number of nodes we're currently connected to. - num_connections: u64, - /// Keeps hash set of peers connected. - peers: HashSet, - /// Number of active connections to pause discovery on. - discovery_max: u64, -} - -impl Display for DiscoveryBehaviour { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str( - format!( - "{{ - user_defined {:?}, - kademlia: {:?}, - mdns: {:?}, - next_kad_random_query: {:?}, - duration_to_next_kad {:?}, - num_connection: {:?}, - peers: {:?}, - discovery_max: {:?} -}}", - self.user_defined, - self.kademlia.is_enabled(), - self.mdns.is_enabled(), - self.next_kad_random_query, - self.duration_to_next_kad, - self.num_connections, - self.peers, - self.discovery_max - ) - .as_str(), - ) - } -} - -impl DiscoveryBehaviour { - /// Create a `DiscoveryBehaviour` from a config. - pub async fn new( - local_peer_id: PeerId, - config: DiscoveryConfig, - ) -> Result { - let DiscoveryConfig { - user_defined, - discovery_max, - enable_kademlia, - enable_mdns, - kademlia_disjoint_query_paths, - } = config; - - let mut peers = HashSet::with_capacity(user_defined.len()); - - // Kademlia config - let kademlia_opt = if enable_kademlia { - let store = MemoryStore::new(local_peer_id.to_owned()); - let mut kad_config = KademliaConfig::default(); - kad_config.disjoint_query_paths(kademlia_disjoint_query_paths); - // TODO: choose a better protocol name - kad_config.set_protocol_name( - "/anoma/kad/anoma/kad/1.0.0".as_bytes().to_vec(), - ); - - let mut kademlia = - Kademlia::with_config(local_peer_id, store, kad_config); - - user_defined - .iter() - .for_each(|PeerAddress { address, peer_id }| { - kademlia.add_address(peer_id, address.clone()); - peers.insert(*peer_id); - }); - - // TODO: For production should node fail when kad failed to - // bootstrap? - if let Err(err) = kademlia.bootstrap() { - tracing::error!("failed to bootstrap kad : {:?}", err); - }; - Some(kademlia) - } else { - None - }; - - let mdns_opt = if enable_mdns { - Some( - Mdns::new(MdnsConfig::default()) - .await - .map_err(Error::FailedMdns)?, - ) - } else { - None - }; - - Ok(DiscoveryBehaviour { - user_defined, - kademlia: kademlia_opt.into(), - mdns: mdns_opt.into(), - next_kad_random_query: None, - duration_to_next_kad: Duration::from_secs(1), - pending_events: VecDeque::new(), - num_connections: 0, - peers, - discovery_max, - }) - } -} - -// Most function here are a wrapper around kad behaviour, -impl NetworkBehaviour for DiscoveryBehaviour { - type OutEvent = DiscoveryEvent; - type ProtocolsHandler = - ToggleIntoProtoHandler>; - - fn new_handler(&mut self) -> Self::ProtocolsHandler { - self.kademlia.new_handler() - } - - /// Look for the address of a peer first in the user defined list then in - /// kademlia then lastly in the local network. Sum all possible address and - /// returns. - fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { - let mut list = self - .user_defined - .iter() - .filter_map(|peer_address| { - if &peer_address.peer_id == peer_id { - Some(peer_address.address.clone()) - } else { - None - } - }) - .collect::>(); - - list.extend(self.kademlia.addresses_of_peer(peer_id)); - - list.extend(self.mdns.addresses_of_peer(peer_id)); - - list - } - - fn inject_connected(&mut self, peer_id: &PeerId) { - tracing::debug!("Injecting connected peer {}", peer_id); - self.peers.insert(*peer_id); - self.pending_events - .push_back(DiscoveryEvent::Connected(*peer_id)); - - self.kademlia.inject_connected(peer_id) - } - - fn inject_disconnected(&mut self, peer_id: &PeerId) { - tracing::debug!("Injecting disconnected peer {}", peer_id); - self.peers.remove(peer_id); - self.pending_events - .push_back(DiscoveryEvent::Disconnected(*peer_id)); - - self.kademlia.inject_disconnected(peer_id) - } - - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - ) { - tracing::debug!( - "Injecting connection established for peer ID {} with endpoint \ - {:#?}", - peer_id, - endpoint - ); - self.num_connections += 1; - - self.kademlia - .inject_connection_established(peer_id, conn, endpoint) - } - - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - ) { - tracing::debug!("Injecting connection closed for peer ID {}", peer_id); - self.num_connections -= 1; - - self.kademlia - .inject_connection_closed(peer_id, conn, endpoint) - } - - fn inject_address_change( - &mut self, - peer: &PeerId, - id: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, - ) { - self.kademlia.inject_address_change(peer, id, old, new) - } - - fn inject_event( - &mut self, - peer_id: PeerId, - connection: ConnectionId, - event: <::Handler as ProtocolsHandler>::OutEvent, - ) { - self.kademlia.inject_event(peer_id, connection, event) - } - - fn inject_addr_reach_failure( - &mut self, - peer_id: Option<&PeerId>, - addr: &Multiaddr, - error: &dyn std::error::Error, - ) { - self.kademlia - .inject_addr_reach_failure(peer_id, addr, error) - } - - fn inject_dial_failure(&mut self, peer_id: &PeerId) { - self.kademlia.inject_dial_failure(peer_id) - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - self.kademlia.inject_new_listen_addr(id, addr) - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - self.kademlia.inject_expired_listen_addr(id, addr); - } - - fn inject_listener_error( - &mut self, - id: ListenerId, - err: &(dyn std::error::Error + 'static), - ) { - self.kademlia.inject_listener_error(id, err) - } - - fn inject_listener_closed( - &mut self, - id: ListenerId, - reason: std::result::Result<(), &io::Error>, - ) { - self.kademlia.inject_listener_closed(id, reason) - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - self.kademlia.inject_new_external_addr(addr) - } - - // This poll function is called by libp2p to fetch/generate new event. First - // in the local queue then in kademlia and lastly in Mdns. - #[allow(clippy::type_complexity)] - fn poll( - &mut self, - cx: &mut Context, - params: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - <::Handler as ProtocolsHandler>::InEvent, - Self::OutEvent, - >, - >{ - // Immediately process the content of `discovered`. - if let Some(ev) = self.pending_events.pop_front() { - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); - } - - // Poll Kademlia return every other event except kad event - while let Poll::Ready(ev) = self.kademlia.poll(cx, params) { - tracing::debug!("Kademlia event {:#?}", ev); - if let NetworkBehaviourAction::GenerateEvent(_kad_ev) = ev { - } else { - return Poll::Ready(ev.map_out(DiscoveryEvent::KademliaEvent)); - } - } - - // Poll the stream that fires when we need to start a random Kademlia - // query. When the stream provides a new value then it tries to look for - // a node and connect to it. - // TODO: explain a bit more the logic happening here - if let Some(next_kad_random_query) = self.next_kad_random_query.as_mut() - { - tracing::debug!( - "Kademlia random query {:#?}", - next_kad_random_query - ); - while next_kad_random_query.poll_next_unpin(cx).is_ready() { - if self.num_connections < self.discovery_max { - let random_peer_id = PeerId::random(); - tracing::debug!( - "Libp2p <= Starting random Kademlia request for {:?}", - random_peer_id - ); - if let Some(k) = self.kademlia.as_mut() { - k.get_closest_peers(random_peer_id); - } - } - - *next_kad_random_query = - stream::interval(self.duration_to_next_kad); - self.duration_to_next_kad = cmp::min( - self.duration_to_next_kad * 2, - Duration::from_secs(60), - ); - } - } - - // Poll mdns. If mdns generated new Discovered event then connect to it - // TODO: refactor this function, it can't be done as the kad done - while let Poll::Ready(ev) = self.mdns.poll(cx, params) { - match ev { - NetworkBehaviourAction::GenerateEvent(event) => match event { - MdnsEvent::Discovered(list) => { - if self.num_connections < self.discovery_max { - // Add any discovered peers to Kademlia - for (peer_id, multiaddr) in list { - if let Some(kad) = self.kademlia.as_mut() { - kad.add_address(&peer_id, multiaddr); - } - } - } else { - tracing::info!( - "max reached {:?}, {:?}", - self.num_connections, - self.discovery_max - ); - // Already over discovery max, don't add discovered - // peers. We could potentially buffer these - // addresses to be added later, but mdns is not an - // important use case and may be removed in future. - } - } - MdnsEvent::Expired(_) => {} - }, - NetworkBehaviourAction::DialAddress { address } => { - return Poll::Ready(NetworkBehaviourAction::DialAddress { - address, - }); - } - NetworkBehaviourAction::DialPeer { peer_id, condition } => { - return Poll::Ready(NetworkBehaviourAction::DialPeer { - peer_id, - condition, - }); - } - // Nothing to notify handler - NetworkBehaviourAction::NotifyHandler { .. } => {} - NetworkBehaviourAction::ReportObservedAddr { - address, - score, - } => { - return Poll::Ready( - NetworkBehaviourAction::ReportObservedAddr { - address, - score, - }, - ); - } - } - } - Poll::Pending - } -} diff --git a/apps/src/lib/node/gossip/p2p/behaviour/mod.rs b/apps/src/lib/node/gossip/p2p/behaviour/mod.rs deleted file mode 100644 index f70a300b9e2..00000000000 --- a/apps/src/lib/node/gossip/p2p/behaviour/mod.rs +++ /dev/null @@ -1,412 +0,0 @@ -mod discovery; -use std::collections::hash_map::DefaultHasher; -use std::convert::TryFrom; -use std::hash::{Hash, Hasher}; -use std::time::Duration; - -use libp2p::gossipsub::subscription_filter::regex::RegexSubscriptionFilter; -use libp2p::gossipsub::subscription_filter::{ - TopicSubscriptionFilter, WhitelistSubscriptionFilter, -}; -use libp2p::gossipsub::{ - self, GossipsubEvent, GossipsubMessage, IdentTopic, IdentityTransform, - MessageAcceptance, MessageAuthenticity, MessageId, TopicHash, - ValidationMode, -}; -use libp2p::identify::{Identify, IdentifyConfig, IdentifyEvent}; -use libp2p::identity::Keypair; -use libp2p::ping::{Ping, PingEvent, PingFailure, PingSuccess}; -use libp2p::swarm::NetworkBehaviourEventProcess; -use libp2p::{NetworkBehaviour, PeerId}; -use namada::proto::{self, Intent, IntentGossipMessage}; -use thiserror::Error; -use tokio::sync::mpsc::Sender; - -use self::discovery::DiscoveryEvent; -use crate::config; -use crate::node::gossip::p2p::behaviour::discovery::{ - DiscoveryBehaviour, DiscoveryConfigBuilder, -}; - -/// Behaviour is composed of a `DiscoveryBehaviour` and an GossipsubBehaviour`. -/// It automatically connect to newly discovered peer, except specified -/// otherwise, and propagates intents to other peers. -#[derive(NetworkBehaviour)] -pub struct Behaviour { - pub intent_gossip_behaviour: Gossipsub, - pub discover_behaviour: DiscoveryBehaviour, - /// The identify protocol allows establishing P2P connections via Kademlia - identify: Identify, - /// Responds to inbound pings and periodically sends outbound pings on - /// every established connection - ping: Ping, - #[behaviour(ignore)] - pub peer_intent_send: Sender, -} - -#[derive(Error, Debug)] -pub enum Error { - #[error("Failed to subscribe")] - FailedSubscription(libp2p::gossipsub::error::SubscriptionError), - #[error("Failed initializing the topic filter: {0}")] - Filter(String), - #[error("Failed initializing the gossip behaviour: {0}")] - GossipConfig(String), - #[error("Failed on the the discovery behaviour config: {0}")] - DiscoveryConfig(String), - #[error("Failed initializing the discovery behaviour: {0}")] - Discovery(discovery::Error), - #[error("Failed initializing mdns: {0}")] - Mdns(std::io::Error), -} - -pub type Gossipsub = libp2p::gossipsub::Gossipsub< - IdentityTransform, - IntentGossipSubscriptionFilter, ->; - -// TODO merge type of config and this one ? Maybe not a good idea -// TODO extends with MaxSubscribionFilter -/// IntentGossipSubscriptionfilter is a wrapper of TopicSubscriptionFilter to -/// allows combination of any sort of filter. -pub enum IntentGossipSubscriptionFilter { - RegexFilter(RegexSubscriptionFilter), - WhitelistFilter(WhitelistSubscriptionFilter), -} - -/// IntentGossipEvent describe events received/sent in the gossipsub network. -/// All information are extracted from the GossipsubEvent type. This type is -/// used as a wrapper of GossipsubEvent in order to have only information of -/// interest and possibly enforce some invariant. -#[derive(Debug)] -pub struct IntentGossipEvent { - /// The PeerId that initially created this message - pub propagation_source: PeerId, - /// The MessageId of this message. This MessageId allows to discriminate - /// already received message - pub message_id: MessageId, - // TODO maybe remove the Option of this field to make mandatory to have an - // id. - /// The peer that transmitted this message to us. It can be anonymous - pub source: Option, - /// The content of the data - pub data: Vec, - /// The topic from which we received the message - pub topic: TopicHash, -} - -impl From for IntentGossipEvent { - /// Transforme a GossipsubEvent into an IntentGossipEvent. This function - /// fails if the gossipsubEvent does not contain a GossipsubMessage. - fn from(event: GossipsubEvent) -> Self { - if let GossipsubEvent::Message { - propagation_source, - message_id, - message: - GossipsubMessage { - source, - data, - topic, - sequence_number: _, - }, - } = event - { - Self { - propagation_source, - message_id, - source, - data, - topic, - } - } else { - panic!("Expected a GossipsubEvent::Message got {:?}", event) - } - } -} - -impl TopicSubscriptionFilter for IntentGossipSubscriptionFilter { - /// tcheck that the proposed topic can be subscribed - fn can_subscribe(&mut self, topic_hash: &TopicHash) -> bool { - match self { - IntentGossipSubscriptionFilter::RegexFilter(filter) => { - filter.can_subscribe(topic_hash) - } - IntentGossipSubscriptionFilter::WhitelistFilter(filter) => { - filter.can_subscribe(topic_hash) - } - } - } -} - -/// [message_id] use the hash of the message data as an id -pub fn message_id(message: &GossipsubMessage) -> MessageId { - let mut hasher = DefaultHasher::new(); - message.data.hash(&mut hasher); - MessageId::from(hasher.finish().to_string()) -} - -impl Behaviour { - /// Create a new behaviour based on the config given - pub async fn new( - key: Keypair, - config: &config::IntentGossiper, - peer_intent_send: Sender, - ) -> Self { - let public_key = key.public(); - let peer_id = PeerId::from_public_key(public_key.clone()); - - // TODO remove hardcoded value and add them to the config Except - // validation_mode, protocol_id_prefix, message_id_fn and - // validate_messages - // Set a custom gossipsub for our use case - let gossipsub_config = gossipsub::GossipsubConfigBuilder::default() - .protocol_id_prefix("intent_gossip") - .heartbeat_interval(Duration::from_secs(1)) - .validation_mode(ValidationMode::Strict) - .message_id_fn(message_id) - .max_transmit_size(16 * 1024 * 1024) - .validate_messages() - .mesh_outbound_min(1) - // TODO bootstrap peers should not be part of the mesh, so all the - // `.mesh` args should be set to 0 https://github.com/libp2p/specs/blob/70d7fda47dda88d828b4db72775c1602de57e91b/pubsub/gossipsub/gossipsub-v1.1.md#recommendations-for-network-operators - .mesh_n_low(2) - .mesh_n(3) - .mesh_n_high(6) - .build() - .unwrap(); - - let filter = match &config.subscription_filter { - crate::config::SubscriptionFilter::RegexFilter(regex) => { - IntentGossipSubscriptionFilter::RegexFilter( - RegexSubscriptionFilter(regex.clone()), - ) - } - crate::config::SubscriptionFilter::WhitelistFilter(topics) => { - IntentGossipSubscriptionFilter::WhitelistFilter( - WhitelistSubscriptionFilter( - topics - .iter() - .map(IdentTopic::new) - .map(TopicHash::from) - .collect(), - ), - ) - } - }; - - let mut intent_gossip_behaviour: Gossipsub = - Gossipsub::new_with_subscription_filter( - MessageAuthenticity::Signed(key), - gossipsub_config, - filter, - ) - .unwrap(); - - // subscribe to all topic listed in the config. - config - .topics - .iter() - .try_for_each(|topic| { - intent_gossip_behaviour - .subscribe(&IdentTopic::new(topic)) - .map_err(Error::FailedSubscription) - // it returns bool signifying if it was already subscribed. - // discard because it can't be false as the config.topics is - // a hash set - .map(|_| ()) - }) - .expect("failed to subscribe to topic"); - - let discover_behaviour = { - // TODO: check that bootstrap_peers are in multiaddr (otherwise it - // fails silently) - let discover_config = - if let Some(discover_config) = &config.discover_peer { - DiscoveryConfigBuilder::default() - .with_user_defined(config.seed_peers.clone()) - .discovery_limit(discover_config.max_discovery_peers) - .with_kademlia(discover_config.kademlia) - .with_mdns(discover_config.mdns) - .use_kademlia_disjoint_query_paths(true) - .build() - .unwrap() - } else { - DiscoveryConfigBuilder::default().build().unwrap() - }; - DiscoveryBehaviour::new(peer_id, discover_config) - .await - .unwrap() - }; - Self { - intent_gossip_behaviour, - discover_behaviour, - identify: Identify::new(IdentifyConfig::new( - "anoma/id/anoma/id/1.0.0".into(), - public_key, - )), - ping: Ping::default(), - peer_intent_send, - } - } - - /// tries to apply a new intent. Fails if the logic fails or if the intent - /// is rejected. If the matchmaker fails the message is only ignore - fn handle_intent(&mut self, intent: Intent) -> MessageAcceptance { - if let Err(err) = self.peer_intent_send.try_send(intent) { - tracing::error!("Error sending intent to the matchmaker: {}", err); - // The buffer is full or the channel is closed - return MessageAcceptance::Ignore; - } - MessageAcceptance::Accept - } - - /// Tries to decoded the arbitrary data in an intent then call - /// [Self::handle_intent]. fails if the data does not contains an intent - fn handle_raw_intent( - &mut self, - data: impl AsRef<[u8]>, - ) -> MessageAcceptance { - match IntentGossipMessage::try_from(data.as_ref()) { - Ok(message) => self.handle_intent(message.intent), - Err(proto::Error::NoIntentError) => { - tracing::info!("Empty message, rejecting it"); - MessageAcceptance::Reject - } - Err(proto::Error::IntentDecodingError(err)) => { - tracing::info!("error while decoding the intent: {:?}", err); - MessageAcceptance::Reject - } - _ => unreachable!(), - } - } -} - -impl NetworkBehaviourEventProcess for Behaviour { - /// When a new event is generated by the intent gossip behaviour - fn inject_event(&mut self, event: GossipsubEvent) { - tracing::info!("received a new message : {:?}", event); - match event { - GossipsubEvent::Message { - message, - propagation_source, - message_id, - } => { - // validity is the type of response return to the network - // (valid|reject|ignore) - let validity = self.handle_raw_intent(message.data); - self.intent_gossip_behaviour - .report_message_validation_result( - &message_id, - &propagation_source, - validity, - ) - .expect("Failed to validate the message"); - } - // When a peer subscribe to a new topic, this node also tries to - // connect to it using the filter defined in the config - GossipsubEvent::Subscribed { peer_id: _, topic } => { - // try to subscribe to the new topic - self.intent_gossip_behaviour - .subscribe(&IdentTopic::new(topic.into_string())) - .map_err(Error::FailedSubscription) - .unwrap_or_else(|e| { - tracing::error!("failed to subscribe: {:?}", e); - false - }); - } - // Nothing to do when you are informed that a peer unsubscribed to a - // topic. - // TODO: It could be interesting to unsubscribe to a topic when the - // node is not connected to anyone else. - GossipsubEvent::Unsubscribed { - peer_id: _, - topic: _, - } => {} - } - } -} - -impl NetworkBehaviourEventProcess for Behaviour { - // The logic is part of the DiscoveryBehaviour, nothing to do here. - fn inject_event(&mut self, event: DiscoveryEvent) { - match event { - DiscoveryEvent::Connected(peer) => { - tracing::info!("Connect to a new peer: {:?}", peer) - } - DiscoveryEvent::Disconnected(peer) => { - tracing::info!("Peer disconnected: {:?}", peer) - } - _ => {} - } - } -} - -impl NetworkBehaviourEventProcess for Behaviour { - fn inject_event(&mut self, event: IdentifyEvent) { - match event { - IdentifyEvent::Received { peer_id, info } => { - tracing::info!("Identified Peer {}", peer_id); - tracing::debug!("protocol_version {}", info.protocol_version); - tracing::debug!("agent_version {}", info.agent_version); - tracing::debug!("listening_addresses {:?}", info.listen_addrs); - tracing::debug!("observed_address {}", info.observed_addr); - tracing::debug!("protocols {:?}", info.protocols); - if let Some(kad) = self.discover_behaviour.kademlia.as_mut() { - // Only the first address is the public IP, the others - // seem to be private - if let Some(addr) = info.listen_addrs.first() { - tracing::info!( - "Routing updated peer ID: {}, address: {}", - peer_id, - addr - ); - let _update = kad.add_address(&peer_id, addr.clone()); - } - } - } - IdentifyEvent::Sent { .. } => (), - IdentifyEvent::Pushed { .. } => (), - IdentifyEvent::Error { peer_id, error } => { - tracing::error!( - "Error while attempting to identify the remote peer {}: \ - {},", - peer_id, - error - ); - } - } - } -} - -impl NetworkBehaviourEventProcess for Behaviour { - fn inject_event(&mut self, event: PingEvent) { - match event.result { - Ok(PingSuccess::Ping { rtt }) => { - tracing::debug!( - "PingSuccess::Ping rtt to {} is {} ms", - event.peer.to_base58(), - rtt.as_millis() - ); - } - Ok(PingSuccess::Pong) => { - tracing::debug!( - "PingSuccess::Pong from {}", - event.peer.to_base58() - ); - } - Err(PingFailure::Timeout) => { - tracing::warn!( - "PingFailure::Timeout {}", - event.peer.to_base58() - ); - } - Err(PingFailure::Other { error }) => { - tracing::warn!( - "PingFailure::Other {}: {}", - event.peer.to_base58(), - error - ); - } - } - } -} diff --git a/apps/src/lib/node/gossip/p2p/identity.rs b/apps/src/lib/node/gossip/p2p/identity.rs deleted file mode 100644 index 42442054c88..00000000000 --- a/apps/src/lib/node/gossip/p2p/identity.rs +++ /dev/null @@ -1,123 +0,0 @@ -use std::fs::OpenOptions; -use std::path::{Path, PathBuf}; - -use libp2p::identity::ed25519::Keypair; -use serde::{Deserialize, Serialize}; -use sha2::{Digest, Sha256}; - -use crate::cli; - -const P2P_KEY_PATH: &str = "gossiper-p2p-private-key.json"; - -/// ed255519 keypair + hash of public key. The keypair used to encrypted the -/// data send in the libp2p network. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Identity { - pub address: String, - #[serde(with = "keypair_serde")] - pub key: Keypair, -} - -// TODO this is needed because libp2p does not export ed255519 serde -// feature maybe a MR for libp2p to export theses functions ? -mod keypair_serde { - use libp2p::identity::ed25519::Keypair; - use serde::de::Error; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - pub fn serialize( - value: &Keypair, - serializer: S, - ) -> Result - where - S: Serializer, - { - let bytes = value.encode(); - let string = hex::encode(&bytes[..]); - string.serialize(serializer) - } - pub fn deserialize<'d, D>(deserializer: D) -> Result - where - D: Deserializer<'d>, - { - let string = String::deserialize(deserializer)?; - let mut bytes = hex::decode(&string).map_err(Error::custom)?; - Keypair::decode(bytes.as_mut()).map_err(Error::custom) - } -} - -impl Identity { - /// Generates a new gossiper keypair and hash. - pub fn new() -> Self { - let key = Keypair::generate(); - let mut hasher = Sha256::new(); - hasher.update(key.public().encode()); - let address = format!("{:.40X}", hasher.finalize()); - Identity { address, key } - } - - /// Load identity from file or generate a new one if none found. - pub fn load_or_gen(base_dir: impl AsRef) -> Identity { - let file_path = Self::file_path(&base_dir); - match OpenOptions::new().read(true).open(&file_path) { - Ok(file) => { - let gossiper: Identity = serde_json::from_reader(file) - .expect("unexpected key encoding"); - gossiper - } - Err(err) => { - if let std::io::ErrorKind::NotFound = err.kind() { - tracing::info!( - "No P2P key found, generating a new one. This will be \ - written into {}", - file_path.to_string_lossy() - ); - Self::gen(base_dir) - } else { - eprintln!( - "Cannot read {}: {}", - file_path.to_string_lossy(), - err - ); - cli::safe_exit(1); - } - } - } - } - - /// Generate a new identity. - pub fn gen(base_dir: impl AsRef) -> Identity { - let file_path = Self::file_path(base_dir); - std::fs::create_dir_all(&file_path.parent().unwrap()).unwrap(); - let file = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(&file_path) - .expect("Couldn't open P2P key file"); - let gossiper = Identity::new(); - serde_json::to_writer_pretty(file, &gossiper) - .expect("Couldn't write private validator key file"); - gossiper - } - - pub fn file_path(base_dir: impl AsRef) -> PathBuf { - base_dir.as_ref().join(P2P_KEY_PATH) - } - - pub fn peer_id(&self) -> libp2p::PeerId { - let pk = self.key.public(); - let pk = libp2p::identity::PublicKey::Ed25519(pk); - libp2p::PeerId::from(pk) - } - - pub fn key(&self) -> libp2p::identity::Keypair { - libp2p::identity::Keypair::Ed25519(self.key.clone()) - } -} - -impl Default for Identity { - fn default() -> Self { - Self::new() - } -} diff --git a/apps/src/lib/node/gossip/p2p/mod.rs b/apps/src/lib/node/gossip/p2p/mod.rs deleted file mode 100644 index 2c135bc9953..00000000000 --- a/apps/src/lib/node/gossip/p2p/mod.rs +++ /dev/null @@ -1,139 +0,0 @@ -pub mod behaviour; -mod identity; - -use std::path::Path; -use std::time::Duration; - -use behaviour::Behaviour; -use libp2p::core::connection::ConnectionLimits; -use libp2p::core::muxing::StreamMuxerBox; -use libp2p::core::transport::Boxed; -use libp2p::dns::DnsConfig; -use libp2p::identity::Keypair; -use libp2p::swarm::SwarmBuilder; -use libp2p::tcp::TcpConfig; -use libp2p::websocket::WsConfig; -use libp2p::{core, mplex, noise, PeerId, Transport, TransportError}; -use namada::proto::Intent; -use thiserror::Error; -use tokio::sync::mpsc::Sender; - -pub use self::identity::Identity; -use crate::config; - -pub type Swarm = libp2p::Swarm; - -#[derive(Error, Debug)] -pub enum Error { - #[error("Failed initializing the transport: {0}")] - Transport(std::io::Error), - #[error("Error with the network behavior: {0}")] - Behavior(crate::node::gossip::p2p::behaviour::Error), - #[error("Error while dialing: {0}")] - Dialing(libp2p::swarm::DialError), - #[error("Error while starting to listing: {0}")] - Listening(TransportError), - #[error("Error decoding peer identity")] - BadPeerIdentity(TransportError), -} -type Result = std::result::Result; - -pub struct P2P(pub Swarm); - -impl P2P { - /// Create a new peer based on the configuration given. Used transport is - /// tcp. A peer participate in the intent gossip system and helps the - /// propagation of intents. - pub async fn new( - config: &config::IntentGossiper, - base_dir: impl AsRef, - peer_intent_send: Sender, - ) -> Result { - let identity = Identity::load_or_gen(base_dir); - let peer_key = identity.key(); - // Id of the node on the libp2p network derived from the public key - let peer_id = identity.peer_id(); - - tracing::info!("Peer id: {:?}", peer_id.clone()); - - let transport = build_transport(&peer_key).await; - - // create intent gossip specific behaviour - let intent_gossip_behaviour = - Behaviour::new(peer_key, config, peer_intent_send).await; - - let connection_limits = build_p2p_connections_limit(); - - // Swarm is - let mut swarm = - SwarmBuilder::new(transport, intent_gossip_behaviour, peer_id) - .connection_limits(connection_limits) - .notify_handler_buffer_size( - std::num::NonZeroUsize::new(20).expect("Not zero"), - ) - .connection_event_buffer_size(64) - .build(); - - swarm - .listen_on(config.address.clone()) - .map_err(Error::Listening)?; - - Ok(Self(swarm)) - } -} - -// TODO explain a bit the choice made here -/// Create transport used by libp2p. See -/// for more information on libp2p -/// transport -pub async fn build_transport( - peer_key: &Keypair, -) -> Boxed<(PeerId, StreamMuxerBox)> { - let transport = { - let tcp_transport = TcpConfig::new().nodelay(true); - let dns_tcp_transport = DnsConfig::system(tcp_transport).await.unwrap(); - let ws_dns_tcp_transport = WsConfig::new(dns_tcp_transport.clone()); - dns_tcp_transport.or_transport(ws_dns_tcp_transport) - }; - - let auth_config = { - let dh_keys = noise::Keypair::::new() - .into_authentic(peer_key) - .expect("Noise key generation failed. Should never happen."); - - noise::NoiseConfig::xx(dh_keys).into_authenticated() - }; - - let mplex_config = { - let mut mplex_config = mplex::MplexConfig::new(); - mplex_config.set_max_buffer_behaviour(mplex::MaxBufferBehaviour::Block); - mplex_config.set_max_buffer_size(usize::MAX); - - let mut yamux_config = libp2p::yamux::YamuxConfig::default(); - yamux_config - .set_window_update_mode(libp2p::yamux::WindowUpdateMode::on_read()); - // TODO: check if its enought - yamux_config.set_max_buffer_size(16 * 1024 * 1024); - yamux_config.set_receive_window_size(16 * 1024 * 1024); - - core::upgrade::SelectUpgrade::new(yamux_config, mplex_config) - }; - - transport - .upgrade(core::upgrade::Version::V1) - .authenticate(auth_config) - .multiplex(mplex_config) - .timeout(Duration::from_secs(20)) - .boxed() -} - -// TODO document choice made here -// TODO inject it in the configuration instead of hard-coding it ? -pub fn build_p2p_connections_limit() -> ConnectionLimits { - ConnectionLimits::default() - .with_max_pending_incoming(Some(10)) - .with_max_pending_outgoing(Some(30)) - .with_max_established_incoming(Some(25)) - .with_max_established_outgoing(Some(25)) - .with_max_established_per_peer(Some(5)) -} diff --git a/apps/src/lib/node/gossip/rpc/client.rs b/apps/src/lib/node/gossip/rpc/client.rs deleted file mode 100644 index f33d6add34d..00000000000 --- a/apps/src/lib/node/gossip/rpc/client.rs +++ /dev/null @@ -1,166 +0,0 @@ -use std::convert::TryFrom; -use std::net::SocketAddr; - -use libp2p::gossipsub::IdentTopic; -use namada::proto::{Intent, IntentGossipMessage}; -use tokio::sync::mpsc::{self, Sender}; -use tokio::sync::oneshot; -use tonic::transport::Server; -use tonic::{Request as TonicRequest, Response as TonicResponse, Status}; - -use crate::config::RpcServer; -use crate::node::gossip::p2p::behaviour::Gossipsub; -use crate::proto::services::rpc_service_server::{ - RpcService, RpcServiceServer, -}; -use crate::proto::services::{rpc_message, RpcMessage, RpcResponse}; -use crate::proto::{IntentMessage, SubscribeTopicMessage}; - -#[derive(Debug)] -struct Rpc { - inject_message: - mpsc::Sender<(rpc_message::Message, oneshot::Sender)>, -} - -#[tonic::async_trait] -impl RpcService for Rpc { - async fn send_message( - &self, - request: TonicRequest, - ) -> Result, Status> { - if let RpcMessage { message: Some(msg) } = request.into_inner() { - let (sender, receiver) = oneshot::channel(); - self.inject_message - .send((msg, sender)) - .await - .map_err(|err| - Status::cancelled(format!{"failed to send message to gossip app: {:?}",err}) - )? - ; - let response = receiver.await.map_err(|err| - Status::data_loss(format!{"failed to receive response from gossip app: {:?}", err}))?; - Ok(TonicResponse::new(response)) - } else { - tracing::error!("Received empty rpc message, nothing can be done"); - Ok(TonicResponse::new(RpcResponse::default())) - } - } -} - -pub async fn rpc_server( - addr: SocketAddr, - inject_message: Sender<( - rpc_message::Message, - oneshot::Sender, - )>, -) -> Result<(), tonic::transport::Error> { - let rpc = Rpc { inject_message }; - let svc = RpcServiceServer::new(rpc); - Server::builder().add_service(svc).serve(addr).await -} - -/// Start a rpc server in it's own thread. The used address to listen is in the -/// `config` argument. All received event by the rpc are send to the channel -/// return by this function. -pub async fn start_rpc_server( - config: &RpcServer, - rpc_sender: mpsc::Sender<( - rpc_message::Message, - tokio::sync::oneshot::Sender, - )>, -) { - let addr = config.address; - tracing::info!("RPC started at {}", config.address); - rpc_server(addr, rpc_sender).await.unwrap(); -} - -pub async fn handle_rpc_event( - event: rpc_message::Message, - gossip_sub: &mut Gossipsub, -) -> (RpcResponse, Option) { - match event { - rpc_message::Message::Intent(message) => { - match IntentMessage::try_from(message) { - Ok(message) => { - // Send the intent to gossip - let gossip_message = - IntentGossipMessage::new(message.intent.clone()); - let intent_bytes = gossip_message.to_bytes(); - - let gossip_result = match gossip_sub - .publish(IdentTopic::new(message.topic), intent_bytes) - { - Ok(message_id) => { - format!( - "Intent published in intent gossiper with \ - message ID: {}", - message_id - ) - } - Err(err) => { - format!( - "Failed to publish intent in gossiper: {:?}", - err - ) - } - }; - ( - RpcResponse { - result: format!( - "Intent received. {}.", - gossip_result, - ), - }, - Some(message.intent), - ) - } - Err(err) => ( - RpcResponse { - result: format!("Error decoding intent: {:?}", err), - }, - None, - ), - } - } - rpc_message::Message::Dkg(dkg_msg) => { - tracing::debug!("dkg not yet implemented {:?}", dkg_msg); - ( - RpcResponse { - result: String::from( - "DKG application not yet - implemented", - ), - }, - None, - ) - } - rpc_message::Message::Topic(topic_message) => { - let topic = SubscribeTopicMessage::from(topic_message); - let topic = IdentTopic::new(&topic.topic); - ( - match gossip_sub.subscribe(&topic) { - Ok(true) => { - let result = format!("Node subscribed to {}", topic); - tracing::info!("{}", result); - RpcResponse { result } - } - Ok(false) => { - let result = - format!("Node already subscribed to {}", topic); - tracing::info!("{}", result); - RpcResponse { result } - } - Err(err) => { - let result = format!( - "failed to subscribe to {}: {:?}", - topic, err - ); - tracing::error!("{}", result); - RpcResponse { result } - } - }, - None, - ) - } - } -} diff --git a/apps/src/lib/node/gossip/rpc/matchmakers.rs b/apps/src/lib/node/gossip/rpc/matchmakers.rs deleted file mode 100644 index c4912c8b96d..00000000000 --- a/apps/src/lib/node/gossip/rpc/matchmakers.rs +++ /dev/null @@ -1,847 +0,0 @@ -//! This module provides connection between an intent gossiper node (the server) -//! and matchmakers (clients) over WebSocket. -//! -//! Both the server and the client can asynchronously listen for new messages -//! and send messages to the other side. - -use std::collections::HashSet; -use std::fmt::Debug; -use std::net::{SocketAddr, ToSocketAddrs}; -use std::sync::atomic::{self, AtomicBool}; -use std::sync::{Arc, RwLock}; - -use borsh::{BorshDeserialize, BorshSerialize}; -use derivative::Derivative; -use message_io::network::{Endpoint, ResourceId, ToRemoteAddr, Transport}; -use message_io::node::{self, NodeHandler, NodeListener}; - -use crate::cli; - -/// Message from intent gossiper to a matchmaker -#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)] -pub enum MsgFromServer { - /// Try to match an intent - AddIntent { id: Vec, data: Vec }, -} - -/// Message from a matchmaker to intent gossiper -#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)] -pub enum MsgFromClient { - /// The intent is invalid and hence it shouldn't be gossiped - InvalidIntent { id: Vec }, - /// The intent constraints are too complex for this matchmaker, gossip it - IntentConstraintsTooComplex { id: Vec }, - /// The matchmaker doesn't care about this intent, gossip it - IgnoredIntent { id: Vec }, - /// Intents were matched into a tx. Remove the matched intents from mempool - /// if the tx gets applied. - Matched { intent_ids: HashSet> }, - /// An intent was accepted and added, but no match found yet. Gossip it - Unmatched { id: Vec }, -} - -/// Intent gossiper server listener handles connections from [`ClientDialer`]s. -#[derive(Derivative)] -#[derivative(Debug)] -pub struct ServerListener { - /// The address on which the server is listening - pub address: SocketAddr, - /// The accepted client connections, shared with the [`ServerDialer`] - clients: Arc>>, - /// A node listener and its abort receiver. These are consumed once the - /// listener is started with [`ServerListener::listen`]. - #[derivative(Debug = "ignore")] - listener: Option<(NodeListener<()>, tokio::sync::mpsc::Receiver<()>)>, -} - -/// Intent gossiper server dialer can send messages to the connected -/// [`ClientListener`]s. -#[derive(Clone, Derivative)] -#[derivative(Debug)] -pub struct ServerDialer { - /// The connection handler - #[derivative(Debug = "ignore")] - handler: NodeHandler<()>, - /// Connection resource ID - resource_id: ResourceId, - /// The accepted client connections, shared with the [`ServerListener`] - clients: Arc>>, - /// A message to abort the server must be sent to stop the - /// [`ServerListener`]. This message will be sent on [`ServerDialer`]'s - /// `drop` call. - abort_send: tokio::sync::mpsc::Sender<()>, -} - -/// Server events are used internally by the async [`ServerListener`]. -#[derive(Clone, Debug)] -enum ServerEvent { - /// New endpoint has been accepted by a listener and considered ready to - /// use. The event contains the resource id of the listener that - /// accepted this connection. - Accepted(Endpoint, ResourceId), - /// Input message received by the network. - Message(Endpoint, MsgFromClient), - /// This event is only dispatched when a connection is lost. - Disconnected(Endpoint), -} - -/// Matchmaker client listener handles a connection from [`ServerDialer`]. -#[derive(Derivative)] -#[derivative(Debug)] -pub struct ClientListener { - /// The connection handler - #[derivative(Debug = "ignore")] - handler: NodeHandler<()>, - /// The server connection endpoint - server: Endpoint, - /// The address on which the client is listening - local_addr: SocketAddr, - /// The client listener. This is consumed once the listener is started with - /// [`ClientListener::listen`]. - #[derivative(Debug = "ignore")] - listener: Option>, - /// Server connection status - is_connected: Arc, -} - -/// Matchmaker client dialer can send messages to the connected -/// [`ServerListener`]. -#[derive(Clone, Derivative)] -#[derivative(Debug)] -pub struct ClientDialer { - /// The address on which the client is listening - pub local_addr: SocketAddr, - /// The server address - server: Endpoint, - /// The connection handler - #[derivative(Debug = "ignore")] - handler: NodeHandler<()>, - /// Server connection status - is_connected: Arc, -} - -impl ServerListener { - /// Create a new intent gossiper node server. Returns a listener and - /// a dialer that can be used to send messages to clients and to shut down - /// the server. - pub fn new_pair(address: impl ToSocketAddrs) -> (Self, ServerDialer) { - let clients: Arc>> = Default::default(); - let (handler, listener) = node::split::<()>(); - - let (resource_id, address) = match handler - .network() - .listen(Transport::Ws, &address) - { - Ok((resource_id, real_addr)) => { - tracing::info!("Matchmakers server running at {}", real_addr); - (resource_id, real_addr) - } - Err(err) => { - eprintln!( - "The matchmakers server cannot listen at {:?}: {}", - address.to_socket_addrs().unwrap().collect::>(), - err - ); - cli::safe_exit(1); - } - }; - - let (abort_send, abort_recv) = tokio::sync::mpsc::channel::<()>(1); - - ( - Self { - address, - clients: clients.clone(), - listener: Some((listener, abort_recv)), - }, - ServerDialer { - handler, - clients, - resource_id, - abort_send, - }, - ) - } - - /// Start the server listener and call `on_msg` on every received message. - /// The listener can be stopped early by [`ServerDialer::shutdown`]. - pub async fn listen(mut self, mut on_msg: impl FnMut(MsgFromClient)) { - // Open a channel for events received from the async listener - let (send, mut recv) = tokio::sync::mpsc::unbounded_channel(); - - // This is safe because `listen` consumes `self` created by - // [`ServerListener::new_pair`] - let (listener, mut abort_recv) = self.listener.take().unwrap(); - - tracing::debug!("Starting intent gossiper matchmakers server..."); - - // Start the async listener that will send server events over the - // channel - let _task = listener.for_each_async(move |event| { - match event.network() { - message_io::network::NetEvent::Message( - endpoint, - mut msg_bytes, - ) => match MsgFromClient::deserialize(&mut msg_bytes) { - Ok(msg) => { - let _ = send.send(ServerEvent::Message(endpoint, msg)); - } - Err(err) => { - tracing::error!( - "Couldn't decode a msg from matchmaker {}: {}", - endpoint, - err - ); - } - }, - message_io::network::NetEvent::Accepted(endpoint, id) => { - tracing::info!( - "Accepted connection from matchmaker {}", - endpoint - ); - let _ = send.send(ServerEvent::Accepted(endpoint, id)); - } - message_io::network::NetEvent::Disconnected(endpoint) => { - tracing::info!("Matchmaker disconnected: {}", endpoint); - let _ = send.send(ServerEvent::Disconnected(endpoint)); - } - message_io::network::NetEvent::Connected(endpoint, status) => { - // Server only gets `NetEvent::Accepted` from connected - // clients - tracing::error!( - "Unexpected server `NetEvent::Connected` with \ - endpoint {}, status {}", - endpoint, - status - ); - } - } - }); - - tracing::debug!("Intent gossiper matchmakers server is ready."); - - // Process the server events - loop { - tokio::select! { - _ = abort_recv.recv() => { - tracing::debug!("Shutting down intent gossiper matchmakers server."); - return; - }, - event = recv.recv() => if let Some(event) = event { - match event { - ServerEvent::Message(endpoint, msg) => { - tracing::debug!( - "Received msg from matchmaker {}: {:?}", - endpoint, - msg - ); - on_msg(msg); - } - ServerEvent::Accepted(endpoint, _id) => { - let mut clients = self.clients.write().unwrap(); - if !clients.insert(endpoint) { - tracing::warn!( - "Accepted matchmaker already known {}", - endpoint - ) - } - } - ServerEvent::Disconnected(endpoint) => { - let mut clients = self.clients.write().unwrap(); - if !clients.remove(&endpoint) { - tracing::warn!( - "Disconnected matchmaker unknown endpoint {}", - endpoint - ) - } - } - } - } - } - } - } -} - -impl ServerDialer { - /// Broadcast a message to all connected matchmaker clients - pub fn send(&mut self, msg: MsgFromServer) { - let net = self.handler.network(); - for client in self.clients.read().unwrap().iter() { - let msg_bytes = msg.try_to_vec().unwrap(); - let status = net.send(*client, &msg_bytes); - tracing::info!( - "Sent msg {:?} to {} with status {:?}", - msg, - client, - status - ); - } - } - - /// Is the server listener ready to start handling incoming connections? - pub fn is_ready(&self) -> bool { - self.handler - .network() - .is_ready(self.resource_id) - .unwrap_or_default() - } - - /// Force shut-down the [`ServerListener`] associated with this dialer. - pub fn shutdown(&mut self) { - self.handler.stop(); - // Send a message to abort and ignore the result - let _ = self.abort_send.blocking_send(()); - } -} - -impl ClientListener { - /// Create a new matchmaker client. Returns a listener and a dialer that - /// can be used to send messages to the server and to shut down the client. - pub fn new_pair(server_addr: impl ToRemoteAddr) -> (Self, ClientDialer) { - let server_addr = server_addr.to_remote_addr().unwrap(); - // Not using message-io signals - let (handler, listener) = node::split::<()>(); - - let (server, local_addr) = match handler - .network() - .connect(Transport::Ws, server_addr.clone()) - { - Ok(res) => res, - Err(err) => { - eprintln!( - "Cannot listen at {} for matchmakers server: {}", - server_addr, err, - ); - cli::safe_exit(1); - } - }; - tracing::info!("Matchmaker client running at {}", local_addr); - - let is_connected = Arc::new(AtomicBool::new(false)); - - ( - Self { - server, - local_addr, - listener: Some(listener), - is_connected: is_connected.clone(), - handler: handler.clone(), - }, - ClientDialer { - server, - local_addr, - handler, - is_connected, - }, - ) - } - - /// Start the client listener and call `on_msg` on every received message. - /// The listener can be stopped early by [`ClientDialer::shutdown`]. - pub fn listen(mut self, mut on_msg: impl FnMut(MsgFromServer)) { - // This is safe because `listen` consumes `self` - let listener = self.listener.take().unwrap(); - - // Start the blocking listener that will call `on_msg` on every message - let server_addr = self.server.addr(); - let local_addr_port = self.local_addr.port(); - - tracing::debug!("Matchmakers client is ready."); - - listener.for_each(move |event| { - tracing::debug!("Client event {:#?}", event); - match event { - node::NodeEvent::Network(net_event) => match net_event { - message_io::network::NetEvent::Message( - endpoint, - mut msg_bytes, - ) => match MsgFromServer::deserialize(&mut msg_bytes) { - Ok(msg) => { - on_msg(msg); - } - Err(err) => { - tracing::error!( - "Couldn't decode a msg from intent gossiper \ - {}: {}", - endpoint, - err - ); - } - }, - message_io::network::NetEvent::Connected( - _endpoint, - established, - ) => { - if established { - tracing::info!( - "Connected to the server at {}. The client is \ - identified by local port: {}", - server_addr, - local_addr_port - ); - } else { - tracing::error!( - "Cannot connect to the server at {}", - server_addr - ) - } - self.is_connected - .store(established, atomic::Ordering::SeqCst); - } - message_io::network::NetEvent::Disconnected(endpoint) => { - tracing::info!("Disconnected from {}", endpoint); - self.is_connected - .store(false, atomic::Ordering::SeqCst); - // Exit on disconnect, a user of this client can - // implement retry logic - self.handler.stop(); - } - message_io::network::NetEvent::Accepted(endpoint, _) => { - // Client only gets `NetEvent::Connected` from connected - // clients - tracing::error!( - "Unexpected client `NetEvent::Accepted` with \ - endpoint {}", - endpoint - ); - } - }, - node::NodeEvent::Signal(()) => { - // unused - } - } - }); - - tracing::debug!("Matchmakers client is shutting down."); - } -} - -impl ClientDialer { - /// Send a message to the intent gossiper server - pub fn send(&mut self, msg: MsgFromClient) { - let net = self.handler.network(); - let msg_bytes = msg.try_to_vec().unwrap(); - let status = net.send(self.server, &msg_bytes); - tracing::info!( - "Sent msg {:?} to {} with status {:?}", - msg, - self.server, - status - ); - } - - /// Is the client connected? - pub fn is_connected(&self) -> bool { - self.is_connected.load(atomic::Ordering::SeqCst) - } - - /// Force shut-down the [`ClientListener`] associated with this dialer. - pub fn shutdown(&mut self) { - self.handler.stop(); - } -} - -impl Drop for ServerDialer { - fn drop(&mut self) { - self.shutdown(); - } -} - -impl Drop for ClientDialer { - fn drop(&mut self) { - self.shutdown(); - } -} - -#[cfg(test)] -mod test { - use std::collections::HashMap; - use std::sync::atomic; - - use itertools::Itertools; - use proptest::prelude::*; - use proptest::prop_state_machine; - use proptest::state_machine::{AbstractStateMachine, StateMachineTest}; - use proptest::test_runner::Config; - use test_log::test; - - use super::*; - - prop_state_machine! { - #![proptest_config(Config { - // Instead of the default 256, we only run 10 because otherwise it - // takes too long - cases: 10, - // 10 second timeout - timeout: 10_000, - .. Config::default() - })] - #[test] - /// A `StateMachineTest` implemented on `AbstractState` - fn connections_state_machine_test(sequential 1..20 => AbstractState); - } - - /// Abstract representation of a state of a server and client(s) - #[derive(Clone, Debug)] - struct AbstractState { - // true == running - server: bool, - clients: HashSet, - } - - /// State of a concrete server and client(s) implementation - #[derive(Default)] - struct ConcreteState { - server: Option, - clients: HashMap, - } - - /// State machine transitions - #[derive(Clone, Debug)] - enum Transition { - StartServer, - StopServer, - StartClient(ClientId), - StopClient(ClientId), - ServerMsg(MsgFromServer), - ClientMsg(ClientId, MsgFromClient), - } - - type ClientId = usize; - - struct TestServer { - /// The address of the server (assigned dynamically) - address: SocketAddr, - /// Runtime for the async listener - rt: tokio::runtime::Runtime, - #[allow(dead_code)] - /// Task that runs the async server listener - listener_handle: tokio::task::JoinHandle<()>, - /// A server dialer can send messages to clients - dialer: ServerDialer, - /// Messages received by the `listener` from clients are forwarded - /// to this receiver, to be checked by the test. - msgs_recv: std::sync::mpsc::Receiver, - } - - struct TestClient { - /// A client dialer can send messages to the server - dialer: ClientDialer, - /// A thread that runs the client listener - listener_handle: std::thread::JoinHandle<()>, - /// Messages received by the `listener` from the server are forwarded - /// to this receiver, to be checked by the test. - msgs_recv: std::sync::mpsc::Receiver, - } - - impl StateMachineTest for AbstractState { - type Abstract = Self; - type ConcreteState = ConcreteState; - - fn init_test( - _initial_state: ::State, - ) -> Self::ConcreteState { - ConcreteState::default() - } - - fn apply_concrete( - mut state: Self::ConcreteState, - transition: ::Transition, - ) -> Self::ConcreteState { - match transition { - Transition::StartServer => { - // Assign port dynamically - let (listener, dialer) = - ServerListener::new_pair("127.0.0.1:0"); - let address = listener.address; - let (msgs_send, msgs_recv) = std::sync::mpsc::channel(); - // Run the listener, we need an async runtime - let rt = tokio::runtime::Runtime::new().unwrap(); - let listener_handle = rt.spawn(async move { - listener - .listen(move |msg| { - msgs_send.send(msg).unwrap(); - }) - .await; - }); - - // Wait for the server to be ready - while !dialer.is_ready() { - println!("Waiting for the server to be ready"); - } - - state.server = Some(TestServer { - address, - rt, - dialer, - listener_handle, - msgs_recv, - }) - } - Transition::StopServer => { - // For the server, we have to send abort signal and drop - // the dialer - let mut server = state.server.take().unwrap(); - server.dialer.shutdown(); - server - .rt - .shutdown_timeout(std::time::Duration::from_secs(2)); - drop(server.dialer); - - if !state.clients.is_empty() { - println!( - "The server is waiting for all the clients to \ - stop..." - ); - while state.clients.values().any(|client| { - client - .dialer - .is_connected - .load(atomic::Ordering::SeqCst) - }) {} - // Stop the clients - for (id, client) in - std::mem::take(&mut state.clients).into_iter() - { - // Ask the client to stop - client.dialer.handler.stop(); - println!("Asking client {} listener to stop", id); - // Wait for it to actually stop - client.listener_handle.join().unwrap(); - println!("Client {} listener stopped", id); - } - println!("Clients stopped"); - } - } - Transition::StartClient(id) => { - let server_addr = state.server.as_ref().unwrap().address; - let (listener, dialer) = - ClientListener::new_pair(server_addr); - let (msgs_send, msgs_recv) = std::sync::mpsc::channel(); - let listener_handle = std::thread::spawn(move || { - listener.listen(|msg| { - msgs_send.send(msg).unwrap(); - }) - }); - - // If there is a server running ... - if let Some(server) = state.server.as_ref() { - // ... wait for the client to connect ... - while !dialer.is_connected() {} - // ... and for the server to accept it - while !server.dialer.clients.read().unwrap().iter().any( - |client| { - // Client's address is added once it's accepted - client.addr() == dialer.local_addr - }, - ) {} - } - - state.clients.insert( - id, - TestClient { - dialer, - listener_handle, - msgs_recv, - }, - ); - } - Transition::StopClient(id) => { - // Remove the client - let client = state.clients.remove(&id).unwrap(); - // Ask the client to stop - client.dialer.handler.stop(); - // Wait for it to actually stop - client.listener_handle.join().unwrap(); - } - Transition::ServerMsg(msg) => { - state.server.as_mut().unwrap().dialer.send(msg.clone()); - - // Post-condition: every client must receive the msg - for client in state.clients.values() { - let recv_msg = client.msgs_recv.recv().unwrap(); - assert_eq!(msg, recv_msg); - } - } - Transition::ClientMsg(id, msg) => { - let client = state.clients.get_mut(&id).unwrap(); - client.dialer.send(msg.clone()); - - // Post-condition: - // If there is a server running ... - if let Some(server) = state.server.as_mut() { - // ... it must receive the msg - let recv_msg = server.msgs_recv.recv().unwrap(); - assert_eq!(msg, recv_msg); - } - } - } - state - } - - fn test_sequential( - initial_state: ::State, - transitions: Vec< - ::Transition, - >, - ) { - let mut state = Self::init_test(initial_state); - for transition in transitions { - state = Self::apply_concrete(state, transition); - Self::invariants(&state); - } - - // Shutdown the server gracefully - if let Some(mut server) = state.server { - server.dialer.shutdown(); - server - .rt - .shutdown_timeout(std::time::Duration::from_secs(4)); - } - // Shutdown any clients too - if !state.clients.is_empty() { - println!( - "The server is waiting for all the clients to stop..." - ); - while state.clients.values().any(|client| { - client.dialer.is_connected.load(atomic::Ordering::SeqCst) - }) {} - println!("Clients stopped"); - } - } - } - - impl AbstractStateMachine for AbstractState { - type State = Self; - type Transition = Transition; - - fn init_state() -> BoxedStrategy { - Just(Self { - server: false, - clients: HashSet::default(), - }) - .boxed() - } - - fn transitions(state: &Self::State) -> BoxedStrategy { - use Transition::*; - if state.clients.is_empty() { - prop_oneof![ - Just(StartServer), - Just(StopServer), - (0..4_usize).prop_map(StartClient), - arb_msg_from_server().prop_map(ServerMsg), - ] - .boxed() - } else { - let ids: Vec<_> = - state.clients.iter().sorted().cloned().collect(); - let arb_id = proptest::sample::select(ids); - prop_oneof![ - Just(StartServer), - Just(StopServer), - (0..4_usize).prop_map(StartClient), - arb_msg_from_server().prop_map(ServerMsg), - arb_id.clone().prop_map(StopClient), - arb_id.prop_flat_map(|id| arb_msg_from_client() - .prop_map(move |msg| { ClientMsg(id, msg) })), - ] - .boxed() - } - } - - fn preconditions( - state: &Self::State, - transition: &Self::Transition, - ) -> bool { - match transition { - Transition::StartServer => !state.server, - Transition::StopServer => state.server, - Transition::StartClient(id) => { - // only start clients if the server is running and this - // client ID is not running - state.server && !state.clients.contains(id) - } - Transition::StopClient(id) => { - // stop only if this client is running - state.clients.contains(id) - } - Transition::ServerMsg(_) => { - // can send only if the server is running - state.server - } - Transition::ClientMsg(id, _) => { - // can send only if the server and this client is running - state.server && state.clients.contains(id) - } - } - } - - fn apply_abstract( - mut state: Self::State, - transition: &Self::Transition, - ) -> Self::State { - match transition { - Transition::StartServer => { - state.server = true; - } - Transition::StopServer => { - state.server = false; - // Clients should disconnect and stop - state.clients = Default::default(); - } - Transition::StartClient(id) => { - state.clients.insert(*id); - } - Transition::StopClient(id) => { - state.clients.remove(id); - } - Transition::ServerMsg(_msg) => { - // no change - } - Transition::ClientMsg(_id, _msg) => { - // no change - } - } - state - } - } - - prop_compose! { - /// Generate an arbitrary MsgFromServer - fn arb_msg_from_server() - (id in proptest::collection::vec(any::(), 1..100), - data in proptest::collection::vec(any::(), 1..100)) - -> MsgFromServer { - MsgFromServer::AddIntent { id, data } - } - } - - /// Generate an arbitrary MsgFromClient - fn arb_msg_from_client() -> impl Strategy { - let arb_intent_id = proptest::collection::vec(any::(), 1..100); - let invalid_intent = arb_intent_id - .clone() - .prop_map(|id| MsgFromClient::InvalidIntent { id }); - let intent_too_complex = arb_intent_id - .clone() - .prop_map(|id| MsgFromClient::IntentConstraintsTooComplex { id }); - let ignored_intent = arb_intent_id - .clone() - .prop_map(|id| MsgFromClient::IgnoredIntent { id }); - let unmatched_intent = arb_intent_id - .clone() - .prop_map(|id| MsgFromClient::Unmatched { id }); - let matched_intent = - proptest::collection::hash_set(arb_intent_id, 1..10).prop_map( - move |intent_ids| MsgFromClient::Matched { intent_ids }, - ); - prop_oneof![ - invalid_intent, - intent_too_complex, - ignored_intent, - matched_intent, - unmatched_intent, - ] - } -} diff --git a/apps/src/lib/node/gossip/rpc/mod.rs b/apps/src/lib/node/gossip/rpc/mod.rs deleted file mode 100644 index 541f5b1eb79..00000000000 --- a/apps/src/lib/node/gossip/rpc/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod client; -pub mod matchmakers; diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index a989338751c..42a0ff1e9da 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -20,7 +20,6 @@ where /// Create a new genesis for the chain with specified id. This includes /// 1. A set of initial users and tokens /// 2. Setting up the validity predicates for both users and tokens - /// 3. A matchmaker pub fn init_chain( &mut self, init: request::InitChain, diff --git a/apps/src/lib/node/matchmaker.rs b/apps/src/lib/node/matchmaker.rs deleted file mode 100644 index 0a01528b007..00000000000 --- a/apps/src/lib/node/matchmaker.rs +++ /dev/null @@ -1,364 +0,0 @@ -use std::env; -use std::net::SocketAddr; -use std::path::{Path, PathBuf}; -use std::rc::Rc; -use std::sync::Arc; - -use borsh::{BorshDeserialize, BorshSerialize}; -use libc::c_void; -use libloading::Library; -use namada::proto::Tx; -use namada::types::address::{self, Address}; -use namada::types::dylib; -use namada::types::intent::{IntentTransfers, MatchedExchanges}; -use namada::types::key::*; -use namada::types::matchmaker::AddIntentResult; -use namada::types::transaction::{hash_tx, Fee, WrapperTx}; -use tendermint_config::net; -use tendermint_config::net::Address as TendermintAddress; - -use super::gossip::rpc::matchmakers::{ - ClientDialer, ClientListener, MsgFromClient, MsgFromServer, -}; -use crate::cli::args; -use crate::client::rpc; -use crate::client::tendermint_rpc_types::TxBroadcastData; -use crate::client::tx::broadcast_tx; -use crate::{cli, config, wasm_loader}; - -/// Run a matchmaker -#[tokio::main] -pub async fn run( - config::Matchmaker { - matchmaker_path, - tx_code_path, - }: config::Matchmaker, - intent_gossiper_addr: SocketAddr, - ledger_addr: TendermintAddress, - tx_signing_key: Rc, - tx_source_address: Address, - wasm_dir: impl AsRef, -) { - let matchmaker_path = matchmaker_path.unwrap_or_else(|| { - eprintln!("Please configure or specify the matchmaker path"); - cli::safe_exit(1); - }); - let tx_code_path = tx_code_path.unwrap_or_else(|| { - eprintln!("Please configure or specify the transaction code path"); - cli::safe_exit(1); - }); - - let (runner, result_handler) = Runner::new_pair( - intent_gossiper_addr, - matchmaker_path, - tx_code_path, - ledger_addr, - tx_signing_key, - tx_source_address, - wasm_dir, - ); - - // Instantiate and run the matchmaker implementation in a dedicated thread - let runner_join_handle = std::thread::spawn(move || { - runner.listen(); - }); - - // Process results async - result_handler.run().await; - - if let Err(error) = runner_join_handle.join() { - eprintln!("Matchmaker runner failed with: {:?}", error); - cli::safe_exit(1) - } -} - -/// A matchmaker receive intents and tries to find a match with previously -/// received intent. -#[derive(Debug)] -pub struct Runner { - matchmaker_path: PathBuf, - /// The client listener. This is consumed once the listener is started with - /// [`Runner::listen`]. - listener: Option, - /// Sender of results of matched intents to the [`ResultHandler`]. - result_send: tokio::sync::mpsc::UnboundedSender, -} - -/// Result handler processes the results sent from the matchmaker [`Runner`]. -#[derive(Debug)] -pub struct ResultHandler { - /// A dialer can send messages to the connected intent gossip node - dialer: ClientDialer, - /// A receiver of matched intents results from the [`Runner`]. - result_recv: tokio::sync::mpsc::UnboundedReceiver, - /// The ledger address to send any crafted transaction to - ledger_address: net::Address, - /// The code of the transaction that is going to be send to a ledger. - tx_code: Vec, - /// A source address for transactions created from intents. - tx_source_address: Address, - /// A keypair that will be used to sign transactions. - tx_signing_key: Rc, -} - -/// The loaded implementation's dylib and its state -#[derive(Debug)] -struct MatchmakerImpl { - /// The matchmaker's state as a raw mutable pointer to allow custom user - /// implementation in a dylib. - /// NOTE: The `state` field MUST be above the `library` field to ensure - /// that its destructor is ran before the implementation code is dropped. - state: MatchmakerState, - /// Matchmaker's implementation loaded from dylib - library: Library, -} - -/// The matchmaker's state as a raw mutable pointer to allow custom user -/// implementation in a dylib -#[derive(Debug)] -struct MatchmakerState(Arc<*mut c_void>); - -impl Runner { - /// Create a new matchmaker and a dialer that can be used to send messages - /// to the intent gossiper node. - pub fn new_pair( - intent_gossiper_addr: SocketAddr, - matchmaker_path: PathBuf, - tx_code_path: PathBuf, - ledger_address: TendermintAddress, - tx_signing_key: Rc, - tx_source_address: Address, - wasm_dir: impl AsRef, - ) -> (Self, ResultHandler) { - // Setup a channel for sending matchmaker results from `Self` to the - // `ResultHandler` - let (result_send, result_recv) = tokio::sync::mpsc::unbounded_channel(); - - // Prepare a client for intent gossiper node connection - let (listener, dialer) = ClientListener::new_pair(intent_gossiper_addr); - - let tx_code = wasm_loader::read_wasm(&wasm_dir, tx_code_path); - - ( - Self { - matchmaker_path, - listener: Some(listener), - result_send, - }, - ResultHandler { - dialer, - result_recv, - ledger_address, - tx_code, - tx_source_address, - tx_signing_key, - }, - ) - } - - pub fn listen(mut self) { - // Load the implementation's dylib and instantiate it. We have to do - // that here instead of `Self::new_pair`, because we cannot send - // it across threads and the listener is launched in a dedicated thread. - - // Check or add a filename extension to matchmaker path - let matchmaker_filename = - if let Some(ext) = self.matchmaker_path.extension() { - if ext != dylib::FILE_EXT { - tracing::warn!( - "Unexpected matchmaker file extension. Expected {}, \ - got {}.", - dylib::FILE_EXT, - ext.to_string_lossy(), - ); - } - self.matchmaker_path.clone() - } else { - let mut filename = self.matchmaker_path.clone(); - filename.set_extension(dylib::FILE_EXT); - filename - }; - - let matchmaker_dylib = if matchmaker_filename.is_absolute() { - // If the path is absolute, use it as is - matchmaker_filename - } else { - // The dylib should be built in the same directory as where Anoma - // binaries are, even when ran via `cargo run`. Anoma's pre-built - // binaries are distributed with the dylib(s) in the same directory. - let dylib_dir_with_bins = || { - let anoma_path = env::current_exe().unwrap(); - anoma_path - .parent() - .map(|path| path.to_owned()) - .unwrap() - .join(&matchmaker_filename) - }; - // Anoma built from source (`make install`) will install the - // dylib(s) to `~/.cargo/lib`. - let dylib_dir_installed = || { - directories::BaseDirs::new() - .expect("Couldn't determine the $HOME directory") - .home_dir() - .join(".cargo") - .join("lib") - .join(&matchmaker_filename) - }; - // Argument with file path relative to the current dir. - let dylib_dir_in_cwd = || { - let anoma_path = env::current_dir().unwrap(); - anoma_path.join(&matchmaker_filename) - }; - - // Try to find the matchmaker lib in either directory (computed - // lazily) - let matchmaker_dylib: Option = - check_file_exists(dylib_dir_with_bins) - .or_else(|| check_file_exists(dylib_dir_installed)) - .or_else(|| check_file_exists(dylib_dir_in_cwd)); - matchmaker_dylib.unwrap_or_else(|| { - panic!( - "The matchmaker library couldn't not be found. Did you \ - build it? Attempted to find it in directories \"{}\", \ - \"{}\" and \"{}\".", - dylib_dir_with_bins().to_string_lossy(), - dylib_dir_installed().to_string_lossy(), - dylib_dir_in_cwd().to_string_lossy(), - ); - }) - }; - tracing::info!( - "Running matchmaker from {}", - matchmaker_dylib.to_string_lossy() - ); - - let matchmaker_code = - unsafe { Library::new(matchmaker_dylib).unwrap() }; - - // Instantiate the matchmaker - let new_matchmaker: libloading::Symbol< - unsafe extern "C" fn() -> *mut c_void, - > = unsafe { matchmaker_code.get(b"_new_matchmaker").unwrap() }; - - let state = MatchmakerState(Arc::new(unsafe { new_matchmaker() })); - - let r#impl = MatchmakerImpl { - state, - library: matchmaker_code, - }; - - // Run the listener for messages from the connected intent gossiper node - self.listener.take().unwrap().listen(|msg| match msg { - MsgFromServer::AddIntent { id, data } => { - self.try_match_intent(&r#impl, id, data); - } - }) - } - - /// add the intent to the matchmaker mempool and tries to find a match for - /// that intent - fn try_match_intent( - &self, - r#impl: &MatchmakerImpl, - intent_id: Vec, - intent_data: Vec, - ) { - let add_intent: libloading::Symbol< - unsafe extern "C" fn( - *mut c_void, - &Vec, - &Vec, - ) -> AddIntentResult, - > = unsafe { r#impl.library.get(b"_add_intent").unwrap() }; - - let result = - unsafe { add_intent(*r#impl.state.0, &intent_id, &intent_data) }; - - self.result_send.send(result).unwrap(); - } -} - -impl Drop for MatchmakerImpl { - fn drop(&mut self) { - let drop_matchmaker: libloading::Symbol< - unsafe extern "C" fn(*mut c_void), - > = unsafe { self.library.get(b"_drop_matchmaker").unwrap() }; - - unsafe { drop_matchmaker(*self.state.0) }; - } -} - -impl ResultHandler { - async fn run(mut self) { - while let Some(result) = self.result_recv.recv().await { - if let Some(tx) = result.tx { - self.submit_tx(tx).await - } - if let Some(intent_ids) = result.matched_intents { - self.dialer.send(MsgFromClient::Matched { intent_ids }) - } - } - } - - async fn submit_tx(&self, tx_data: Vec) { - let tx_code = self.tx_code.clone(); - let matches = MatchedExchanges::try_from_slice(&tx_data[..]).unwrap(); - let intent_transfers = IntentTransfers { - matches, - source: self.tx_source_address.clone(), - }; - let tx_data = intent_transfers.try_to_vec().unwrap(); - let to_broadcast = { - let epoch = rpc::query_epoch(args::Query { - ledger_address: self.ledger_address.clone(), - }) - .await; - let tx = WrapperTx::new( - Fee { - amount: 0.into(), - token: address::xan(), - }, - &self.tx_signing_key, - epoch, - 0.into(), - Tx::new(tx_code, Some(tx_data)).sign(&self.tx_signing_key), - // TODO: Actually use the fetched encryption key - Default::default(), - ); - let wrapper_hash = hash_tx(&tx.try_to_vec().unwrap()).to_string(); - - let decrypted_hash = tx.tx_hash.to_string(); - TxBroadcastData::Wrapper { - tx: tx - .sign(&self.tx_signing_key) - .expect("Wrapper tx signing keypair should be correct"), - wrapper_hash, - decrypted_hash, - } - }; - - let response = - broadcast_tx(self.ledger_address.clone(), &to_broadcast).await; - match response { - Ok(tx_response) => { - tracing::info!( - "Injected transaction from matchmaker with result: {:#?}", - tx_response - ); - } - Err(err) => { - tracing::error!( - "Matchmaker error in submitting a transaction to the \ - ledger: {}", - err - ); - } - } - } -} - -/// Return the path of the file returned by `lazy_path` argument, if it exists. -fn check_file_exists(lazy_path: impl Fn() -> PathBuf) -> Option { - let path = lazy_path(); - if path.exists() { Some(path) } else { None } -} diff --git a/apps/src/lib/node/mod.rs b/apps/src/lib/node/mod.rs index 22655478680..370e1150a28 100644 --- a/apps/src/lib/node/mod.rs +++ b/apps/src/lib/node/mod.rs @@ -1,3 +1 @@ -pub mod gossip; pub mod ledger; -pub mod matchmaker; diff --git a/apps/src/lib/proto/README.md b/apps/src/lib/proto/README.md deleted file mode 100644 index 33a3b4673d6..00000000000 --- a/apps/src/lib/proto/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Protobuf Compiled Definitions - -**The source files in the `generated` directory are generated by build.rs, do not edit them by hand** diff --git a/apps/src/lib/proto/generated.rs b/apps/src/lib/proto/generated.rs deleted file mode 100644 index 4e379ae78bd..00000000000 --- a/apps/src/lib/proto/generated.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod services; diff --git a/apps/src/lib/proto/generated/.gitignore b/apps/src/lib/proto/generated/.gitignore deleted file mode 100644 index 6f5f3d11d3e..00000000000 --- a/apps/src/lib/proto/generated/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.rs diff --git a/apps/src/lib/proto/mod.rs b/apps/src/lib/proto/mod.rs deleted file mode 100644 index 363f4e54555..00000000000 --- a/apps/src/lib/proto/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod generated; -mod types; - -pub use generated::services; -pub use types::{IntentMessage, RpcMessage, SubscribeTopicMessage}; diff --git a/apps/src/lib/proto/types.rs b/apps/src/lib/proto/types.rs deleted file mode 100644 index c8ef8af7e34..00000000000 --- a/apps/src/lib/proto/types.rs +++ /dev/null @@ -1,148 +0,0 @@ -use std::convert::{TryFrom, TryInto}; - -use namada::proto::{Dkg, Error, Intent}; - -use super::generated::services; - -pub type Result = std::result::Result; - -pub enum RpcMessage { - IntentMessage(IntentMessage), - SubscribeTopicMessage(SubscribeTopicMessage), - Dkg(Dkg), -} - -impl From for services::RpcMessage { - fn from(message: RpcMessage) -> Self { - let message = match message { - RpcMessage::IntentMessage(m) => { - services::rpc_message::Message::Intent(m.into()) - } - RpcMessage::SubscribeTopicMessage(m) => { - services::rpc_message::Message::Topic(m.into()) - } - RpcMessage::Dkg(d) => services::rpc_message::Message::Dkg(d.into()), - }; - services::RpcMessage { - message: Some(message), - } - } -} - -impl RpcMessage { - pub fn new_intent(intent: Intent, topic: String) -> Self { - RpcMessage::IntentMessage(IntentMessage::new(intent, topic)) - } - - pub fn new_topic(topic: String) -> Self { - RpcMessage::SubscribeTopicMessage(SubscribeTopicMessage::new(topic)) - } - - pub fn new_dkg(dkg: Dkg) -> Self { - RpcMessage::Dkg(dkg) - } -} - -#[derive(Debug, PartialEq)] -pub struct IntentMessage { - pub intent: Intent, - pub topic: String, -} - -impl TryFrom for IntentMessage { - type Error = Error; - - fn try_from(message: services::IntentMessage) -> Result { - match message.intent { - Some(intent) => Ok(IntentMessage { - intent: intent.try_into()?, - topic: message.topic, - }), - None => Err(Error::NoIntentError), - } - } -} - -impl From for services::IntentMessage { - fn from(message: IntentMessage) -> Self { - services::IntentMessage { - intent: Some(message.intent.into()), - topic: message.topic, - } - } -} - -impl IntentMessage { - pub fn new(intent: Intent, topic: String) -> Self { - IntentMessage { intent, topic } - } -} - -#[derive(Debug, PartialEq)] -pub struct SubscribeTopicMessage { - pub topic: String, -} - -impl From for SubscribeTopicMessage { - fn from(message: services::SubscribeTopicMessage) -> Self { - SubscribeTopicMessage { - topic: message.topic, - } - } -} - -impl From for services::SubscribeTopicMessage { - fn from(message: SubscribeTopicMessage) -> Self { - services::SubscribeTopicMessage { - topic: message.topic, - } - } -} - -impl SubscribeTopicMessage { - pub fn new(topic: String) -> Self { - SubscribeTopicMessage { topic } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_intent_message() { - let data = "arbitrary data".as_bytes().to_owned(); - let intent = Intent::new(data); - let topic = "arbitrary string".to_owned(); - let intent_message = IntentMessage::new(intent.clone(), topic.clone()); - - let intent_rpc_message = RpcMessage::new_intent(intent, topic); - let services_rpc_message: services::RpcMessage = - intent_rpc_message.into(); - match services_rpc_message.message { - Some(services::rpc_message::Message::Intent(i)) => { - let message_from_types = - IntentMessage::try_from(i).expect("no intent"); - assert_eq!(intent_message, message_from_types); - } - _ => panic!("no intent message"), - } - } - - #[test] - fn test_topic_message() { - let topic = "arbitrary string".to_owned(); - let topic_message = SubscribeTopicMessage::new(topic.clone()); - - let topic_rpc_message = RpcMessage::new_topic(topic); - let services_rpc_message: services::RpcMessage = - topic_rpc_message.into(); - match services_rpc_message.message { - Some(services::rpc_message::Message::Topic(t)) => { - let message_from_types = SubscribeTopicMessage::from(t); - assert_eq!(topic_message, message_from_types); - } - _ => panic!("no intent message"), - } - } -} diff --git a/apps/src/lib/wallet/defaults.rs b/apps/src/lib/wallet/defaults.rs index 6a4f9dacc33..ad519d64dea 100644 --- a/apps/src/lib/wallet/defaults.rs +++ b/apps/src/lib/wallet/defaults.rs @@ -4,8 +4,7 @@ pub use dev::{ addresses, albert_address, albert_keypair, bertha_address, bertha_keypair, christel_address, christel_keypair, daewon_address, daewon_keypair, keys, - matchmaker_address, matchmaker_keypair, validator_address, - validator_keypair, validator_keys, + validator_address, validator_keypair, validator_keys, }; use namada::ledger::{eth_bridge, governance, pos}; use namada::types::address::Address; @@ -107,7 +106,6 @@ mod dev { ("bertha".into(), bertha_keypair()), ("christel".into(), christel_keypair()), ("daewon".into(), daewon_keypair()), - ("matchmaker".into(), matchmaker_keypair()), ("validator".into(), validator_keypair()), ] } @@ -118,7 +116,6 @@ mod dev { ("pos".into(), pos::ADDRESS), ("pos_slash_pool".into(), pos::SLASH_POOL_ADDRESS), ("governance".into(), governance::vp::ADDRESS), - ("matchmaker".into(), matchmaker_address()), ("validator".into(), validator_address()), ("albert".into(), albert_address()), ("bertha".into(), bertha_address()), @@ -158,11 +155,6 @@ mod dev { Address::decode("atest1v4ehgw36ggcnsdee8qerswph8y6ry3p5xgunvve3xaqngd3kxc6nqwz9gseyydzzg5unys3ht2n48q").expect("The token address decoding shouldn't fail") } - /// An established matchmaker address for testing & development - pub fn matchmaker_address() -> Address { - Address::decode("atest1v4ehgw36x5mnswphx565gv2yxdprzvf5gdp523jpxy6rvv6zxaznzsejxeznzseh8pp5ywz93xwala").expect("The address decoding shouldn't fail") - } - pub fn albert_keypair() -> common::SecretKey { // generated from // [`namada::types::key::ed25519::gen_keypair`] @@ -222,16 +214,4 @@ mod dev { let ed_sk = ed25519::SecretKey::try_from_slice(&bytes).unwrap(); ed_sk.try_to_sk().unwrap() } - - pub fn matchmaker_keypair() -> common::SecretKey { - // generated from - // [`namada::types::key::ed25519::gen_keypair`] - let bytes = [ - 91, 67, 244, 37, 241, 33, 157, 218, 37, 172, 191, 122, 75, 2, 44, - 219, 28, 123, 44, 34, 9, 240, 244, 49, 112, 192, 180, 98, 142, 160, - 182, 14, - ]; - let ed_sk = ed25519::SecretKey::try_from_slice(&bytes).unwrap(); - ed_sk.try_to_sk().unwrap() - } } diff --git a/documentation/docs/src/testnets/internal-testnet-1.md b/documentation/docs/src/testnets/internal-testnet-1.md index d4ad45adb6d..ef376341d8d 100644 --- a/documentation/docs/src/testnets/internal-testnet-1.md +++ b/documentation/docs/src/testnets/internal-testnet-1.md @@ -165,7 +165,7 @@ specified. However, any transparent account can sign these transactions. ### Build from Source -Build the provided validity predicate, transaction and matchmaker wasm modules +Build the provided validity predicate and transaction wasm modules ```shell make build-wasm-scripts-docker diff --git a/documentation/docs/src/user-guide/getting-started.md b/documentation/docs/src/user-guide/getting-started.md index 6f2ce00e309..03e77110ba8 100644 --- a/documentation/docs/src/user-guide/getting-started.md +++ b/documentation/docs/src/user-guide/getting-started.md @@ -3,7 +3,7 @@ This guide assumes that the Namada binaries are [installed](./install.md) and available on path. These are: - `namada`: The main binary that can be used to interact with all the components of Namada -- `namadan`: The ledger and intent gossiper node +- `namadan`: The ledger node - `namadac`: The client - `namadaw`: The wallet diff --git a/documentation/docs/src/user-guide/intent-gossiper-and-matchmaker.md b/documentation/docs/src/user-guide/intent-gossiper-and-matchmaker.md deleted file mode 100644 index abacd929d60..00000000000 --- a/documentation/docs/src/user-guide/intent-gossiper-and-matchmaker.md +++ /dev/null @@ -1,124 +0,0 @@ -# The Intent gossiper and Matchmaker - -To run an intent gossiper node with an RPC server through which new intents can be submitted: - -```shell -anoma node gossip --rpc "127.0.0.1:26660" -``` - -To run a token exchange matchmaker: - -```shell -anoma node matchmaker --matchmaker-path libmm_token_exch --tx-code-path wasm/tx_from_intent.wasm --ledger-address "127.0.0.1:26657" --source matchmaker --signing-key matchmaker -``` - -Mind that `matchmaker` must be an established account known on the ledger with a key in your wallet that will be used to sign transactions submitted from the matchmaker to the ledger. - -This pre-built matchmaker implementation is [the fungible token exchange `mm_token_exch`](https://github.com/anoma/anoma/blob/5051b3abbc645aed2e40e1ff8db2d682e9a115e9/matchmaker/mm_token_exch/src/lib.rs), that is being used together with [the pre-built `tx_from_intent` transaction WASM](https://github.com/anoma/anoma/blob/5051b3abbc645aed2e40e1ff8db2d682e9a115e9/wasm/wasm_source/src/lib.rs#L140) to submit transaction from matched intents to the ledger. - -## ✋ Example intents - -1) Lets create some accounts: - - ```shell - anoma wallet key gen --alias alberto --unsafe-dont-encrypt - anoma client init-account --alias alberto-account --public-key alberto --source alberto - - anoma wallet key gen --alias christel --unsafe-dont-encrypt - anoma client init-account --alias christel-account --public-key christel --source christel - - anoma wallet key gen --alias bertha --unsafe-dont-encrypt - anoma client init-account --alias bertha-account --public-key bertha --source bertha - - anoma wallet key gen --alias my-matchmaker --unsafe-dont-encrypt - anoma client init-account --alias my-matchmaker-account --public-key my-matchmaker --source my-matchmaker - ``` - -1) We then need some tokens: - - ```shell - anoma client transfer --source faucet --target alberto-account --signer alberto-account --token BTC --amount 1000 - anoma client transfer --source faucet --target bertha-account --signer bertha-account --token ETH --amount 1000 - anoma client transfer --source faucet --target christel-account --signer christel-account --token NAM --amount 1000 - ``` - -1) Lets export some variables: - - ```shell - export ALBERTO=$(anoma wallet address find --alias alberto-account | cut -c 28- | tr -d '\n') - export CHRISTEL=$(anoma wallet address find --alias christel-account | cut -c 28- | tr -d '\n') - export BERTHA=$(anoma wallet address find --alias bertha-account | cut -c 28- | tr -d '\n') - export NAM=$(anoma wallet address find --alias NAM | cut -c 28- | tr -d '\n') - export BTC=$(anoma wallet address find --alias BTC | cut -c 28- | tr -d '\n') - export ETH=$(anoma wallet address find --alias ETH | cut -c 28- | tr -d '\n') - ``` - -1) Create files with the intents description: - - ```shell - echo '[{"addr":"'$ALBERTO'","key":"'$ALBERTO'","max_sell":"70","min_buy":"100","rate_min":"2","token_buy":"'$NAM'","token_sell":"'$BTC'","vp_path": "wasm_for_tests/vp_always_true.wasm"}]' > intent.A.data - - echo '[{"addr":"'$BERTHA'","key":"'$BERTHA'","max_sell":"300","min_buy":"50","rate_min":"0.7","token_buy":"'$BTC'","token_sell":"'$ETH'"}]' > intent.B.data - - echo '[{"addr":"'$CHRISTEL'","key":"'$CHRISTEL'","max_sell":"200","min_buy":"20","rate_min":"0.5","token_buy":"'$ETH'","token_sell":"'$NAM'"}]' > intent.C.data - ``` - -1) Start the ledger, intent gossiper and the matchmaker. Instruct the intent gossiper to subscribe to a topic "asset_v1": - - ```shell - anoma node ledger run - - anoma node gossip --rpc "127.0.0.1:26660" - - anoma node matchmaker --matchmaker-path wasm/mm_token_exch.wasm --tx-code-path wasm/tx_from_intent.wasm --ledger-address "127.0.0.1:26657" --source mm-1 --signing-key mm-1 - - anoma client subscribe-topic --node "http://127.0.0.1:26660" --topic "asset_v1" - ``` - -1) Submit the intents (the target gossiper node must be running an RPC server): - - ```shell - anoma client intent --data-path intent.A.data --topic "asset_v1" --signing-key alberto --node "http://127.0.0.1:26660" - anoma client intent --data-path intent.B.data --topic "asset_v1" --signing-key bertha --node "http://127.0.0.1:26660" - anoma client intent --data-path intent.C.data --topic "asset_v1" --signing-key christel --node "http://127.0.0.1:26660" - ``` - - The matchmaker should find a match from these intents and submit a transaction to the ledger that performs the n-party transfers of tokens. - -1) You can check the balances with: - - ```shell - anoma client balance --owner alberto-account - anoma client balance --owner bertha-account - anoma client balance --owner christel-account - ``` - -## 🤝 Custom matchmaker - -A custom matchmaker code can be built from [`matchmaker/mm_template`](https://github.com/anoma/anoma/tree/master/matchmaker/mm_template). - -The `anoma_macros::Matchmaker` macro can be used to derive the binding code for the matchmaker runner on any custom implementation, e.g.: - -```rust -#[derive(Default, Matchmaker)] -struct MyMatchmaker; -``` - -This macro requires that there is a `Default` implementation (derived or custom) for the matchmaker, which can be used by the runner to instantiate the matchmaker. - -The matchmaker must also implement `AddIntent`, e.g.: - -```rust -impl AddIntent for MyMatchmaker { - // This function will be called when a new intent is received - fn add_intent( - &mut self, - _intent_id: &Vec, - _intent_data: &Vec, - ) -> AddIntentResult { - AddIntentResult::default() - } -} -``` - -To submit a transaction from the matchmaker, add it to the `AddIntentResult` along with a hash set of the intent IDs that were matched into the transaction. diff --git a/genesis/dev.toml b/genesis/dev.toml index 4c48bcc279e..35b8140ea9e 100644 --- a/genesis/dev.toml +++ b/genesis/dev.toml @@ -114,11 +114,6 @@ address = "atest1v4ehgw36x3qng3jzggu5yvpsxgcngv2xgguy2dpkgvu5x33kx3pr2w2zgep5xwf public_key = "d06f8d4f897f329a50fd23ba5d2503bbe22fab2f14d5f625e07a65f617eb2778" vp = "vp_user" -[established.matchmaker] -address = "atest1v4ehgw36x5mnswphx565gv2yxdprzvf5gdp523jpxy6rvv6zxaznzsejxeznzseh8pp5ywz93xwala" -public_key = "f4fe03b0d3130f077e4d51cc7748baac998750476bef994a0a73ac4e7d183168" -vp = "vp_user" - # An implicit account present at genesis. # Daewon (a1qyqzsqqqqqcyvvf5xcu5vd6rg4z5233hg9pn23pjgdryzdjy8pz52wzxxscnvvjxx3rryvzz8y5p6mtz) diff --git a/genesis/e2e-tests-single-node.toml b/genesis/e2e-tests-single-node.toml index 96fd787ca2d..54961a99fe5 100644 --- a/genesis/e2e-tests-single-node.toml +++ b/genesis/e2e-tests-single-node.toml @@ -1,6 +1,5 @@ # Genesis configuration source for E2E tests with: -# - 1 genesis validator and intent # gossip nodes -# - a matchmaker configured on the first validator node +# - 1 genesis validator # - User accounts same as the ones in "dev" build (Albert, Bertha, Christel) genesis_time = "2021-09-30T10:00:00Z" @@ -18,13 +17,6 @@ staking_reward_vp = "vp_user" # We set the port to be the default+1000, so that if a local node was running at # the same time as the E2E tests, it wouldn't affect them. net_address = "127.0.0.1:27656" -# This has to be an alias of one of the established accounts -matchmaker_account = "matchmaker" -# A matchmaker dylib program's name (the platform specific extension -# `(dll|dylib|so)` is added by Anoma) -matchmaker_code = "libmm_token_exch" -# A transaction WASM code used by the matchmaker -matchmaker_tx = "wasm/tx_from_intent.wasm" # Some tokens present at genesis. @@ -41,8 +33,6 @@ Christel = 1000000 Daewon = 1000000 faucet = 9223372036854 "faucet.public_key" = 100 -matchmaker = 1000000 -"matchmaker.public_key" = 1000 "validator-0.public_key" = 100 [token.BTC] @@ -110,9 +100,6 @@ faucet = 9223372036854 [established.faucet] vp = "vp_testnet_faucet" -[established.matchmaker] -vp = "vp_user" - [established.Albert] vp = "vp_user" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index afa49c66abd..2d6e06d66d4 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,5 +1,5 @@ -//! Anoma macros for generating WASM binding code for transactions, validity -//! predicates and matchmaker. +//! Anoma macros for generating WASM binding code for transactions and validity +//! predicates. #![doc(html_favicon_url = "https://dev.anoma.net/master/favicon.png")] #![doc(html_logo_url = "https://dev.anoma.net/master/rustdoc-logo.png")] @@ -8,7 +8,7 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{parse_macro_input, DeriveInput, ItemFn}; +use syn::{parse_macro_input, ItemFn}; /// Generate WASM binding for a transaction main entrypoint function. /// @@ -123,114 +123,3 @@ pub fn validity_predicate( }; TokenStream::from(gen) } - -/// Derive dynamic library binding for a matchmaker implementation. -/// -/// This macro requires that the data structure implements -/// [`std::default::Default`] that is used to instantiate the matchmaker and -/// `namada::types::matchmaker::AddIntent` to implement a custom matchmaker -/// algorithm. -/// -/// # Examples -/// -/// ```compiler_fail -/// use namada::types::matchmaker::AddIntent; -/// use namada_macros::Matchmaker; -/// -/// #[derive(Default, Matchmaker)] -/// struct Matchmaker; -/// -/// impl AddIntent for Matchmaker { -/// } -/// ``` -#[proc_macro_derive(Matchmaker)] -pub fn matchmaker(input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as DeriveInput); - let ident = &ast.ident; - // Print out the original AST and add add_intent implementation and binding - let gen = quote! { - - /// Add the marker trait - #[automatically_derived] - impl namada::types::matchmaker::Matchmaker for #ident {} - - /// Instantiate a new matchmaker and return a pointer to it. The caller is - /// responsible for making sure that the memory of the pointer will be dropped, - /// which can be done by calling the `_drop_matchmaker` function. - #[no_mangle] - #[automatically_derived] - fn _new_matchmaker() -> *mut std::ffi::c_void { - let state = Box::new(#ident::default()); - let state_ptr = Box::into_raw(state) as *mut std::ffi::c_void; - state_ptr - } - - /// Drop the matchmaker's state to reclaim its memory - #[no_mangle] - #[automatically_derived] - fn _drop_matchmaker(state_ptr: *mut std::ffi::c_void) { - // The state will be dropped on going out of scope - let _state = unsafe { Box::from_raw(state_ptr as *mut #ident) }; - } - - /// Ask the matchmaker to process a new intent - #[allow(clippy::ptr_arg)] - #[no_mangle] - #[automatically_derived] - fn _add_intent( - state_ptr: *mut std::ffi::c_void, - intent_id: &Vec, - intent_data: &Vec, - ) -> namada::types::matchmaker::AddIntentResult { - let state_ptr = state_ptr as *mut #ident; - let mut state: #ident = unsafe { std::ptr::read(state_ptr) }; - let result = state.add_intent(intent_id, intent_data); - unsafe { std::ptr::write(state_ptr, state) }; - result - } - }; - TokenStream::from(gen) -} - -/// Generate WASM binding for matchmaker filter main entrypoint function. -/// -/// This macro expects a function with signature: -/// -/// ```compiler_fail -/// fn validate_intent(intent: Vec) -> bool -/// ``` -#[proc_macro_attribute] -pub fn filter(_attr: TokenStream, input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as ItemFn); - let ident = &ast.sig.ident; - let gen = quote! { - // Use `wee_alloc` as the global allocator. - #[global_allocator] - static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; - - #ast - - /// The module interface callable by wasm runtime - #[no_mangle] - extern "C" fn _validate_intent( - intent_data_ptr: u64, - intent_data_len: u64, - ) -> u64 { - let get_data = |ptr, len| { - let slice = unsafe { - core::slice::from_raw_parts(ptr as *const u8, len as _) - }; - slice.to_vec() - }; - - if #ident( - get_data(intent_data_ptr, intent_data_len), - ) { - 0 - } else { - 1 - } - } - }; - TokenStream::from(gen) -} diff --git a/proto/services.proto b/proto/services.proto deleted file mode 100644 index 9f16dddb91d..00000000000 --- a/proto/services.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package services; - -import "types.proto"; - -service RPCService { - rpc SendMessage(RpcMessage) returns (RpcResponse); -} - -message IntentMessage{ - types.Intent intent = 1; - string topic = 2; -} - -message SubscribeTopicMessage{ - string topic = 2; -} - -message RpcMessage { - oneof message { - IntentMessage intent = 1; - SubscribeTopicMessage topic = 2; - types.Dkg dkg = 3; - } -} - -message RpcResponse { - string result = 1; -} diff --git a/proto/types.proto b/proto/types.proto index b4a0162b50c..58494ec8248 100644 --- a/proto/types.proto +++ b/proto/types.proto @@ -11,24 +11,8 @@ message Tx { google.protobuf.Timestamp timestamp = 3; } -message Intent { - bytes data = 1; - google.protobuf.Timestamp timestamp = 2; -} - -message IntentGossipMessage{ - // TODO remove oneof because it's not used so far - oneof msg { - Intent intent = 1; - } -} - -message Dkg { - string data = 1; -} +message Dkg { string data = 1; } -message DkgGossipMessage{ - oneof dkg_message { - Dkg dkg = 1; - } +message DkgGossipMessage { + oneof dkg_message { Dkg dkg = 1; } } diff --git a/shared/build.rs b/shared/build.rs index 3c5ffb41f1d..74dd72b7537 100644 --- a/shared/build.rs +++ b/shared/build.rs @@ -58,9 +58,6 @@ fn main() { tonic_build::configure() .out_dir("src/proto/generated") .format(use_rustfmt) - // TODO try to add json encoding to simplify use for user - // .type_attribute("types.Intent", "#[derive(serde::Serialize, - // serde::Deserialize)]") .protoc_arg("--experimental_allow_proto3_optional") .compile(&[format!("{}/types.proto", PROTO_SRC)], &[PROTO_SRC]) .unwrap(); diff --git a/shared/src/proto/mod.rs b/shared/src/proto/mod.rs index aa971f0b969..564a26e941e 100644 --- a/shared/src/proto/mod.rs +++ b/shared/src/proto/mod.rs @@ -3,9 +3,7 @@ pub mod generated; mod types; -pub use types::{ - Dkg, Error, Intent, IntentGossipMessage, IntentId, Signed, SignedTxData, Tx, -}; +pub use types::{Dkg, Error, Signed, SignedTxData, Tx}; #[cfg(test)] mod tests { diff --git a/shared/src/proto/types.rs b/shared/src/proto/types.rs index 7a936dd58fd..6f7efd4b70f 100644 --- a/shared/src/proto/types.rs +++ b/shared/src/proto/types.rs @@ -1,6 +1,4 @@ -use std::collections::hash_map::DefaultHasher; use std::convert::{TryFrom, TryInto}; -use std::fmt::Display; use std::hash::{Hash, Hasher}; use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; @@ -17,12 +15,8 @@ use crate::types::transaction::hash_tx; pub enum Error { #[error("Error decoding a transaction from bytes: {0}")] TxDecodingError(prost::DecodeError), - #[error("Error decoding an IntentGossipMessage from bytes: {0}")] - IntentDecodingError(prost::DecodeError), #[error("Error decoding an DkgGossipMessage from bytes: {0}")] DkgDecodingError(prost::DecodeError), - #[error("Intent is empty")] - NoIntentError, #[error("Dkg is empty")] NoDkgError, #[error("Timestamp is empty")] @@ -221,53 +215,6 @@ impl Tx { } } -#[derive(Clone, Debug, PartialEq)] -pub struct IntentGossipMessage { - pub intent: Intent, -} - -impl TryFrom<&[u8]> for IntentGossipMessage { - type Error = Error; - - fn try_from(intent_bytes: &[u8]) -> Result { - let intent = types::IntentGossipMessage::decode(intent_bytes) - .map_err(Error::IntentDecodingError)?; - match &intent.msg { - Some(types::intent_gossip_message::Msg::Intent(intent)) => { - Ok(IntentGossipMessage { - intent: intent.clone().try_into()?, - }) - } - None => Err(Error::NoIntentError), - } - } -} - -impl From for types::IntentGossipMessage { - fn from(message: IntentGossipMessage) -> Self { - types::IntentGossipMessage { - msg: Some(types::intent_gossip_message::Msg::Intent( - message.intent.into(), - )), - } - } -} - -impl IntentGossipMessage { - pub fn new(intent: Intent) -> Self { - IntentGossipMessage { intent } - } - - pub fn to_bytes(&self) -> Vec { - let mut bytes = vec![]; - let message: types::IntentGossipMessage = self.clone().into(); - message - .encode(&mut bytes) - .expect("encoding an intent gossip message failed"); - bytes - } -} - #[allow(dead_code)] #[derive(Clone, Debug, PartialEq)] pub struct DkgGossipMessage { @@ -317,67 +264,6 @@ impl DkgGossipMessage { } } -#[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub struct Intent { - pub data: Vec, - pub timestamp: DateTimeUtc, -} - -impl TryFrom for Intent { - type Error = Error; - - fn try_from(intent: types::Intent) -> Result { - let timestamp = match intent.timestamp { - Some(t) => t.try_into().map_err(Error::InvalidTimestamp)?, - None => return Err(Error::NoTimestampError), - }; - Ok(Intent { - data: intent.data, - timestamp, - }) - } -} - -impl From for types::Intent { - fn from(intent: Intent) -> Self { - let timestamp = Some(intent.timestamp.into()); - types::Intent { - data: intent.data, - timestamp, - } - } -} - -impl Intent { - pub fn new(data: Vec) -> Self { - Intent { - data, - timestamp: DateTimeUtc::now(), - } - } - - pub fn id(&self) -> IntentId { - let mut hasher = DefaultHasher::new(); - self.hash(&mut hasher); - IntentId::from(hasher.finish().to_string()) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntentId(pub Vec); - -impl>> From for IntentId { - fn from(value: T) -> Self { - Self(value.into()) - } -} - -impl Display for IntentId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", hex::encode(&self.0)) - } -} - #[allow(dead_code)] #[derive(Clone, Debug, PartialEq)] pub struct Dkg { @@ -431,18 +317,6 @@ mod tests { } } - #[test] - fn test_intent_gossip_message() { - let data = "arbitrary data".as_bytes().to_owned(); - let intent = Intent::new(data); - let message = IntentGossipMessage::new(intent); - - let bytes = message.to_bytes(); - let message_from_bytes = IntentGossipMessage::try_from(bytes.as_ref()) - .expect("decoding failed"); - assert_eq!(message_from_bytes, message); - } - #[test] fn test_dkg_gossip_message() { let data = "arbitrary string".to_owned(); @@ -455,26 +329,6 @@ mod tests { assert_eq!(message_from_bytes, message); } - #[test] - fn test_intent() { - let data = "arbitrary data".as_bytes().to_owned(); - let intent = Intent::new(data.clone()); - - let types_intent: types::Intent = intent.clone().into(); - let intent_from_types = - Intent::try_from(types_intent).expect("no timestamp"); - assert_eq!(intent_from_types, intent); - - let types_intent = types::Intent { - data, - timestamp: None, - }; - match Intent::try_from(types_intent) { - Err(Error::NoTimestampError) => {} - _ => panic!("unexpected result"), - } - } - #[test] fn test_dkg() { let data = "arbitrary string".to_owned(); diff --git a/shared/src/types/intent.rs b/shared/src/types/intent.rs deleted file mode 100644 index c3effbb4fc6..00000000000 --- a/shared/src/types/intent.rs +++ /dev/null @@ -1,475 +0,0 @@ -//! Intent data definitions and transaction and validity-predicate helpers. - -use std::collections::{HashMap, HashSet}; -use std::convert::TryFrom; -use std::io::ErrorKind; - -use borsh::{BorshDeserialize, BorshSerialize}; -use derivative::Derivative; -use rust_decimal::prelude::*; -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -use crate::proto::Signed; -use crate::types::address::Address; -use crate::types::storage::{DbKeySeg, Key, KeySeg}; -use crate::types::token; - -/// A simple intent for fungible token trade -#[derive( - Debug, - Clone, - PartialEq, - BorshSerialize, - BorshDeserialize, - Serialize, - Deserialize, - Eq, -)] -pub struct FungibleTokenIntent { - /// List of exchange definitions - pub exchange: HashSet>, -} - -#[derive( - Debug, - Clone, - BorshSerialize, - BorshDeserialize, - Serialize, - Deserialize, - Eq, - PartialEq, - Hash, - PartialOrd, - Derivative, -)] -/// The definition of an intent exchange -pub struct Exchange { - /// The source address - pub addr: Address, - /// The token to be sold - pub token_sell: Address, - /// The minimum rate - pub rate_min: DecimalWrapper, - /// The maximum amount of token to be sold - pub max_sell: token::Amount, - /// The token to be bought - pub token_buy: Address, - /// The amount of token to be bought - pub min_buy: token::Amount, - /// The vp code - #[derivative(Debug = "ignore")] - pub vp: Option>, -} - -/// These are transfers crafted from matched [`Exchange`]s created by a -/// matchmaker program. -#[derive( - Debug, - Clone, - BorshSerialize, - BorshDeserialize, - Serialize, - Deserialize, - PartialEq, -)] -pub struct MatchedExchanges { - /// Transfers crafted from the matched intents - pub transfers: HashSet, - // TODO benchmark between an map or a set, see which is less costly - /// The exchanges that were matched - pub exchanges: HashMap>, - /// The intents - // TODO: refactor this without duplicating stuff. The exchanges in the - // `exchanges` hashmap are already contained in the FungibleTokenIntents - // belows - pub intents: HashMap>, -} - -/// These are transfers crafted from matched [`Exchange`]s with a source address -/// that is expected to sign this data. -#[derive( - Debug, - Clone, - BorshSerialize, - BorshDeserialize, - Serialize, - Deserialize, - PartialEq, -)] -pub struct IntentTransfers { - /// Matched exchanges - pub matches: MatchedExchanges, - /// Source address that should sign this data - pub source: Address, -} - -/// Struct holding a safe rapresentation of a float -#[derive( - Debug, - Clone, - Eq, - PartialEq, - Hash, - PartialOrd, - Serialize, - Deserialize, - Default, -)] -pub struct DecimalWrapper(pub Decimal); - -impl From for DecimalWrapper { - fn from(decimal: Decimal) -> Self { - DecimalWrapper(decimal) - } -} - -#[allow(missing_docs)] -#[derive(Error, Debug)] -pub enum Error { - #[error("Error parsing as decimal: {0}.")] - DecimalParseError(String), -} - -impl TryFrom for DecimalWrapper { - type Error = Error; - - fn try_from(amount: token::Amount) -> Result { - let decimal = Decimal::from_i128(amount.change()); - - match decimal { - Some(d) => Ok(DecimalWrapper::from(d)), - None => Err(Error::DecimalParseError(amount.change().to_string())), - } - } -} - -impl FromStr for DecimalWrapper { - type Err = Error; - - fn from_str(s: &str) -> Result { - let decimal = Decimal::from_str(s) - .map_err(|e| Self::Err::DecimalParseError(e.to_string())); - - match decimal { - Ok(d) => Ok(DecimalWrapper::from(d)), - Err(e) => Err(e), - } - } -} - -impl BorshSerialize for DecimalWrapper { - fn serialize( - &self, - writer: &mut W, - ) -> std::io::Result<()> { - let vec = self.0.to_string().as_bytes().to_vec(); - let bytes = vec - .try_to_vec() - .expect("DecimalWrapper bytes encoding shouldn't fail"); - writer.write_all(&bytes) - } -} - -impl BorshDeserialize for DecimalWrapper { - fn deserialize(buf: &mut &[u8]) -> std::io::Result { - // deserialize the bytes first - let bytes: Vec = - BorshDeserialize::deserialize(buf).map_err(|e| { - std::io::Error::new( - ErrorKind::InvalidInput, - format!("Error decoding DecimalWrapper: {}", e), - ) - })?; - let decimal_str: &str = - std::str::from_utf8(bytes.as_slice()).map_err(|e| { - std::io::Error::new( - ErrorKind::InvalidInput, - format!("Error decoding decimal: {}", e), - ) - })?; - let decimal = Decimal::from_str(decimal_str).map_err(|e| { - std::io::Error::new( - ErrorKind::InvalidInput, - format!("Error decoding decimal: {}", e), - ) - })?; - Ok(DecimalWrapper(decimal)) - } -} - -impl MatchedExchanges { - /// Create an empty [`MatchedExchanges`]. - pub fn empty() -> Self { - Self { - transfers: HashSet::new(), - exchanges: HashMap::new(), - intents: HashMap::new(), - } - } -} - -const INVALID_INTENT_STORAGE_KEY: &str = "invalid_intent"; - -/// Obtain a storage key for user's invalid intent set. -pub fn invalid_intent_key(owner: &Address) -> Key { - Key::from(owner.to_db_key()) - .push(&INVALID_INTENT_STORAGE_KEY.to_owned()) - .expect("Cannot obtain a storage key") -} - -/// Check if the given storage key is a key for a set of intent sig. If it is, -/// returns the owner. -pub fn is_invalid_intent_key(key: &Key) -> Option<&Address> { - match &key.segments[..] { - [DbKeySeg::AddressSeg(owner), DbKeySeg::StringSeg(key)] - if key == INVALID_INTENT_STORAGE_KEY => - { - Some(owner) - } - _ => None, - } -} - -#[cfg(test)] -mod tests { - use std::env; - use std::iter::FromIterator; - - use constants::*; - - use super::*; - use crate::ledger::storage::types::{decode, encode}; - use crate::types::key; - - #[test] - fn test_encode_decode_intent_transfer_without_vp() { - let bertha_addr = Address::from_str(BERTHA).unwrap(); - let albert_addr = Address::from_str(ALBERT).unwrap(); - - let bertha_keypair = key::testing::keypair_1(); - let albert_keypair = key::testing::keypair_2(); - - let exchange_one = Exchange { - addr: Address::from_str(BERTHA).unwrap(), - token_buy: Address::from_str(XAN).unwrap(), - token_sell: Address::from_str(BTC).unwrap(), - max_sell: token::Amount::from(100), - min_buy: token::Amount::from(1), - rate_min: DecimalWrapper::from_str("0.1").unwrap(), - vp: None, - }; - let exchange_two = Exchange { - addr: Address::from_str(ALBERT).unwrap(), - token_buy: Address::from_str(BTC).unwrap(), - token_sell: Address::from_str(XAN).unwrap(), - max_sell: token::Amount::from(1), - min_buy: token::Amount::from(100), - rate_min: DecimalWrapper::from_str("10").unwrap(), - vp: None, - }; - - let signed_exchange_one = Signed::new(&bertha_keypair, exchange_one); - let signed_exchange_two = Signed::new(&bertha_keypair, exchange_two); - - let mut it = MatchedExchanges::empty(); - it.exchanges = HashMap::<_, _>::from_iter( - vec![ - (bertha_addr.clone(), signed_exchange_one.clone()), - (albert_addr.clone(), signed_exchange_two.clone()), - ] - .into_iter(), - ); - - it.intents = HashMap::<_, _>::from_iter( - vec![ - ( - bertha_addr.clone(), - Signed::new( - &bertha_keypair, - FungibleTokenIntent { - exchange: HashSet::from_iter(vec![ - signed_exchange_one, - ]), - }, - ), - ), - ( - albert_addr.clone(), - Signed::new( - &albert_keypair, - FungibleTokenIntent { - exchange: HashSet::from_iter(vec![ - signed_exchange_two, - ]), - }, - ), - ), - ] - .into_iter(), - ); - - it.transfers = HashSet::<_>::from_iter( - vec![ - token::Transfer { - source: bertha_addr.clone(), - target: albert_addr.clone(), - token: Address::from_str(BTC).unwrap(), - amount: token::Amount::from(100), - }, - token::Transfer { - source: albert_addr, - target: bertha_addr, - token: Address::from_str(XAN).unwrap(), - amount: token::Amount::from(1), - }, - ] - .into_iter(), - ); - - let encoded_intent_transfer = encode(&it); - let decoded_intent_transfer: MatchedExchanges = - decode(encoded_intent_transfer).unwrap(); - - assert!(decoded_intent_transfer == it); - } - - #[test] - fn test_encode_decode_intent_transfer_with_vp() { - let bertha_addr = Address::from_str(BERTHA).unwrap(); - let albert_addr = Address::from_str(ALBERT).unwrap(); - - let bertha_keypair = key::testing::keypair_1(); - let albert_keypair = key::testing::keypair_2(); - - let working_dir = env::current_dir().unwrap(); - - let exchange_one = Exchange { - addr: Address::from_str(BERTHA).unwrap(), - token_buy: Address::from_str(XAN).unwrap(), - token_sell: Address::from_str(BTC).unwrap(), - max_sell: token::Amount::from(100), - min_buy: token::Amount::from(1), - rate_min: DecimalWrapper::from_str("0.1").unwrap(), - vp: Some( - std::fs::read(format!( - "{}/../{}", - working_dir.to_string_lossy(), - VP_ALWAYS_FALSE_WASM - )) - .unwrap(), - ), - }; - let exchange_two = Exchange { - addr: Address::from_str(ALBERT).unwrap(), - token_buy: Address::from_str(BTC).unwrap(), - token_sell: Address::from_str(XAN).unwrap(), - max_sell: token::Amount::from(1), - min_buy: token::Amount::from(100), - rate_min: DecimalWrapper::from_str("10").unwrap(), - vp: Some( - std::fs::read(format!( - "{}/../{}", - working_dir.to_string_lossy(), - VP_ALWAYS_TRUE_WASM - )) - .unwrap(), - ), - }; - - let signed_exchange_one = Signed::new(&bertha_keypair, exchange_one); - let signed_exchange_two = Signed::new(&bertha_keypair, exchange_two); - - let mut it = MatchedExchanges::empty(); - it.exchanges = HashMap::<_, _>::from_iter( - vec![ - (bertha_addr.clone(), signed_exchange_one.clone()), - (albert_addr.clone(), signed_exchange_two.clone()), - ] - .into_iter(), - ); - - it.intents = HashMap::<_, _>::from_iter( - vec![ - ( - bertha_addr.clone(), - Signed::new( - &bertha_keypair, - FungibleTokenIntent { - exchange: HashSet::from_iter(vec![ - signed_exchange_one, - ]), - }, - ), - ), - ( - albert_addr.clone(), - Signed::new( - &albert_keypair, - FungibleTokenIntent { - exchange: HashSet::from_iter(vec![ - signed_exchange_two, - ]), - }, - ), - ), - ] - .into_iter(), - ); - - it.transfers = HashSet::<_>::from_iter( - vec![ - token::Transfer { - source: bertha_addr.clone(), - target: albert_addr.clone(), - token: Address::from_str(BTC).unwrap(), - amount: token::Amount::from(100), - }, - token::Transfer { - source: albert_addr, - target: bertha_addr, - token: Address::from_str(XAN).unwrap(), - amount: token::Amount::from(1), - }, - ] - .into_iter(), - ); - - let encoded_intent_transfer = encode(&it); - let decoded_intent_transfer: MatchedExchanges = - decode(encoded_intent_transfer).unwrap(); - - assert!(decoded_intent_transfer == it); - } - - #[cfg(test)] - #[allow(dead_code)] - mod constants { - - // User addresses - pub const ALBERT: &str = "atest1v4ehgw368ycryv2z8qcnxv3cxgmrgvjpxs6yg333gym5vv2zxepnj334g4rryvj9xucrgve4x3xvr4"; - pub const BERTHA: &str = "atest1v4ehgw36xvcyyvejgvenxs34g3zygv3jxqunjd6rxyeyys3sxy6rwvfkx4qnj33hg9qnvse4lsfctw"; - pub const CHRISTEL: &str = "atest1v4ehgw36x3qng3jzggu5yvpsxgcngv2xgguy2dpkgvu5x33kx3pr2w2zgep5xwfkxscrxs2pj8075p"; - - // Fungible token addresses - pub const XAN: &str = "atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5"; - pub const BTC: &str = "atest1v4ehgw36xdzryve5gsc52veeg5cnsv2yx5eygvp38qcrvd29xy6rys6p8yc5xvp4xfpy2v694wgwcp"; - pub const ETH: &str = "atest1v4ehgw36xqmr2d3nx3ryvd2xxgmrq33j8qcns33sxezrgv6zxdzrydjrxveygd2yxumrsdpsf9jc2p"; - pub const DOT: &str = "atest1v4ehgw36gg6nvs2zgfpyxsfjgc65yv6pxy6nwwfsxgungdzrggeyzv35gveyxsjyxymyz335hur2jn"; - - // Bite-sized tokens - pub const SCHNITZEL: &str = "atest1v4ehgw36xue5xvf5xvuyzvpjx5un2v3k8qeyvd3cxdqns32p89rrxd6xx9zngvpegccnzs699rdnnt"; - pub const APFEL: &str = "atest1v4ehgw36gfryydj9g3p5zv3kg9znyd358ycnzsfcggc5gvecgc6ygs2rxv6ry3zpg4zrwdfeumqcz9"; - pub const KARTOFFEL: &str = "atest1v4ehgw36gep5ysecxq6nyv3jg3zygv3e89qn2vp48pryxsf4xpznvve5gvmy23fs89pryvf5a6ht90"; - - // Paths to the WASMs used for tests - pub const TX_TRANSFER_WASM: &str = "wasm/tx_transfer.wasm"; - pub const VP_USER_WASM: &str = "wasm/vp_user.wasm"; - pub const TX_NO_OP_WASM: &str = "wasm_for_tests/tx_no_op.wasm"; - pub const VP_ALWAYS_TRUE_WASM: &str = - "wasm_for_tests/vp_always_true.wasm"; - pub const VP_ALWAYS_FALSE_WASM: &str = - "wasm_for_tests/vp_always_false.wasm"; - } -} diff --git a/shared/src/types/matchmaker.rs b/shared/src/types/matchmaker.rs deleted file mode 100644 index 5ee67a83ed4..00000000000 --- a/shared/src/types/matchmaker.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Matchmaker types - -use std::collections::HashSet; - -/// A matchmaker marker trait. This should not be implemented manually. Instead, -/// it is added by the derive `Matchmaker` macro, which also adds necessary -/// binding code for matchmaker dylib runner. -pub trait Matchmaker: AddIntent {} - -/// A matchmaker must implement this trait -pub trait AddIntent: Default { - // TODO: For some reason, using `&[u8]` causes the `decode_intent_data` to - // fail decoding - /// Add a new intent to matchmaker's state - #[allow(clippy::ptr_arg)] - fn add_intent( - &mut self, - intent_id: &Vec, - intent_data: &Vec, - ) -> AddIntentResult; -} - -/// The result of calling matchmaker's `add_intent` function -#[derive(Clone, Debug, Default)] -pub struct AddIntentResult { - /// A transaction matched from the intent, if any - pub tx: Option>, - /// The intent IDs that were matched into the tx, if any - pub matched_intents: Option>>, -} diff --git a/shared/src/types/mod.rs b/shared/src/types/mod.rs index 4b8d7288caf..240fbdb70cc 100644 --- a/shared/src/types/mod.rs +++ b/shared/src/types/mod.rs @@ -6,10 +6,8 @@ pub mod dylib; pub mod governance; pub mod hash; pub mod ibc; -pub mod intent; pub mod internal; pub mod key; -pub mod matchmaker; pub mod nft; pub mod storage; pub mod time; diff --git a/shared/src/vm/mod.rs b/shared/src/vm/mod.rs index 88c88038366..2e14666f816 100644 --- a/shared/src/vm/mod.rs +++ b/shared/src/vm/mod.rs @@ -1,5 +1,4 @@ -//! Virtual machine modules for running transactions, validity predicates, -//! matchmaker and matchmaker's filter. +//! Virtual machine modules for running transactions and validity predicates. use std::ffi::c_void; use std::marker::PhantomData; diff --git a/shared/src/vm/types.rs b/shared/src/vm/types.rs index c2a9ef11cbc..480190ad082 100644 --- a/shared/src/vm/types.rs +++ b/shared/src/vm/types.rs @@ -29,9 +29,6 @@ pub struct VpInput<'a> { pub verifiers: &'a BTreeSet
, } -/// Input for matchmaker wasm module call -pub type MatchmakerInput = Vec; - /// Key-value pair represents data from account's subspace #[derive(Clone, Debug, BorshSerialize, BorshDeserialize)] pub struct KeyVal { diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 4ae17e8fff5..cc07e3704f7 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -38,7 +38,6 @@ file-serve = "0.2.0" fs_extra = "1.2.0" hex = "0.4.3" itertools = "0.10.0" -libp2p = "0.38.0" pretty_assertions = "0.7.2" # A fork with state machine testing proptest = {git = "https://github.com/heliaxdev/proptest", branch = "tomas/sm"} diff --git a/tests/src/e2e.rs b/tests/src/e2e.rs index a9eb2b2cf5f..0afc343098c 100644 --- a/tests/src/e2e.rs +++ b/tests/src/e2e.rs @@ -12,7 +12,6 @@ //! `ANOMA_E2E_KEEP_TEMP=true`. pub mod eth_bridge_tests; -pub mod gossip_tests; pub mod helpers; pub mod ledger_tests; pub mod setup; diff --git a/tests/src/e2e/gossip_tests.rs b/tests/src/e2e/gossip_tests.rs deleted file mode 100644 index 5da19c0758e..00000000000 --- a/tests/src/e2e/gossip_tests.rs +++ /dev/null @@ -1,348 +0,0 @@ -//! By default, these tests will run in release mode. This can be disabled -//! by setting environment variable `ANOMA_E2E_DEBUG=true`. For debugging, -//! you'll typically also want to set `RUST_BACKTRACE=1`, e.g.: -//! -//! ```ignore,shell -//! ANOMA_E2E_DEBUG=true RUST_BACKTRACE=1 cargo test e2e::gossip_tests -- --test-threads=1 --nocapture -//! ``` -//! -//! To keep the temporary files created by a test, use env var -//! `ANOMA_E2E_KEEP_TEMP=true`. - -use std::env; -use std::fs::OpenOptions; -use std::path::PathBuf; - -use color_eyre::eyre::Result; -use escargot::CargoBuild; -use serde_json::json; -use setup::constants::*; - -use super::setup::ENV_VAR_DEBUG; -use crate::e2e::helpers::{ - find_address, get_actor_rpc, get_gossiper_mm_server, -}; -use crate::e2e::setup::{self, Bin, Who}; -use crate::{run, run_as}; - -/// Test that when we "run-gossip" a peer with no seeds should fail -/// bootstrapping kademlia. A peer with a seed should be able to -/// bootstrap kademia and connect to the other peer. -/// In this test we: -/// 1. Check that a gossip node can start and stop cleanly -/// 2. Check that two peers connected to the same seed node discover each other -#[test] -#[ignore] // this is not currently being developed, run with `cargo test -- --ignored` -fn run_gossip() -> Result<()> { - let test = - setup::network(|genesis| setup::add_validators(2, genesis), None)?; - - // 1. Start the first gossip node and then stop it - let mut node_0 = - run_as!(test, Who::Validator(0), Bin::Node, &["gossip"], Some(40))?; - node_0.send_control('c')?; - node_0.exp_eof()?; - drop(node_0); - - // 2. Check that two peers connected to the same seed node discover each - // other. Start the first gossip node again (the seed node). - let mut node_0 = - run_as!(test, Who::Validator(0), Bin::Node, &["gossip"], Some(40))?; - let (_unread, matched) = node_0.exp_regex(r"Peer id: PeerId\(.*\)")?; - let node_0_peer_id = matched - .trim() - .rsplit_once('\"') - .unwrap() - .0 - .rsplit_once('\"') - .unwrap() - .1; - let _bg_node_0 = node_0.background(); - - // Start the second gossip node (a peer node) - let mut node_1 = - run_as!(test, Who::Validator(1), Bin::Node, &["gossip"], Some(40))?; - - let (_unread, matched) = node_1.exp_regex(r"Peer id: PeerId\(.*\)")?; - let node_1_peer_id = matched - .trim() - .rsplit_once('\"') - .unwrap() - .0 - .rsplit_once('\"') - .unwrap() - .1; - node_1.exp_string(&format!( - "Connect to a new peer: PeerId(\"{}\")", - node_0_peer_id - ))?; - let _bg_node_1 = node_1.background(); - - // Start the third gossip node (another peer node) - let mut node_2 = - run_as!(test, Who::Validator(2), Bin::Node, &["gossip"], Some(20))?; - // The third node should connect to node 1 via Identify and Kademlia peer - // discovery protocol - node_2.exp_string(&format!( - "Connect to a new peer: PeerId(\"{}\")", - node_1_peer_id - ))?; - node_2.exp_string(&format!("Identified Peer {}", node_1_peer_id))?; - node_2 - .exp_string(&format!("Routing updated peer ID: {}", node_1_peer_id))?; - - Ok(()) -} - -/// This test runs a ledger node and 2 gossip nodes. It then crafts 3 intents -/// and sends them to the matchmaker. The matchmaker should be able to match -/// them into a transfer transaction and submit it to the ledger. -#[test] -#[ignore] // this is not currently being developed, run with `cargo test -- --ignored` -fn match_intents() -> Result<()> { - let test = setup::single_node_net()?; - - // Make sure that the default matchmaker is built - println!("Building the matchmaker \"mm_token_exch\" implementation..."); - let run_debug = match env::var(ENV_VAR_DEBUG) { - Ok(val) => val.to_ascii_lowercase() != "false", - _ => false, - }; - let manifest_path = test - .working_dir - .join("matchmaker") - .join("mm_token_exch") - .join("Cargo.toml"); - let cmd = CargoBuild::new().manifest_path(manifest_path); - let cmd = if run_debug { cmd } else { cmd.release() }; - let msgs = cmd.exec().unwrap(); - for msg in msgs { - msg.unwrap(); - } - println!("Done building the matchmaker."); - - let mut ledger = - run_as!(test, Who::Validator(0), Bin::Node, &["ledger"], Some(40))?; - ledger.exp_string("Anoma ledger node started")?; - ledger.exp_string("No state could be found")?; - // Wait to commit a block - ledger.exp_regex(r"Committed block hash.*, height: [0-9]+")?; - let bg_ledger = ledger.background(); - - let intent_a_path_input = test.test_dir.path().join("intent.A.data"); - let intent_b_path_input = test.test_dir.path().join("intent.B.data"); - let intent_c_path_input = test.test_dir.path().join("intent.C.data"); - - let albert = find_address(&test, ALBERT)?; - let bertha = find_address(&test, BERTHA)?; - let christel = find_address(&test, CHRISTEL)?; - let xan = find_address(&test, XAN)?; - let btc = find_address(&test, BTC)?; - let eth = find_address(&test, ETH)?; - let intent_a_json = json!([ - { - "key": bertha, - "addr": bertha, - "min_buy": "100.0", - "max_sell": "70", - "token_buy": xan, - "token_sell": btc, - "rate_min": "2", - "vp_path": test.working_dir.join(VP_ALWAYS_TRUE_WASM).to_string_lossy().into_owned(), - } - ]); - - let intent_b_json = json!([ - { - "key": albert, - "addr": albert, - "min_buy": "50", - "max_sell": "300", - "token_buy": btc, - "token_sell": eth, - "rate_min": "0.7" - } - ]); - let intent_c_json = json!([ - { - "key": christel, - "addr": christel, - "min_buy": "20", - "max_sell": "200", - "token_buy": eth, - "token_sell": xan, - "rate_min": "0.5" - } - ]); - generate_intent_json(intent_a_path_input.clone(), intent_a_json); - generate_intent_json(intent_b_path_input.clone(), intent_b_json); - generate_intent_json(intent_c_path_input.clone(), intent_c_json); - - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); - let validator_one_gossiper = - get_gossiper_mm_server(&test, &Who::Validator(0)); - - // The RPC port starts at 27660 (see `setup::network`) - let rpc_port = 27660; - let rpc_address = format!("127.0.0.1:{}", rpc_port); - - // Start intent gossiper node - let mut gossiper = run_as!( - test, - Who::Validator(0), - Bin::Node, - &["gossip", "--rpc", &rpc_address], - Some(20) - )?; - - // Wait gossip to start - gossiper.exp_string(&format!("RPC started at {}", rpc_address))?; - let _bg_gossiper = gossiper.background(); - - // Start matchmaker - let mut matchmaker = run_as!( - test, - Who::Validator(0), - Bin::Node, - &[ - "matchmaker", - "--source", - "matchmaker", - "--signing-key", - "matchmaker-key", - "--ledger-address", - &validator_one_rpc, - "--intent-gossiper", - &validator_one_gossiper, - ], - Some(40) - )?; - - // Wait for the matchmaker to start - matchmaker.exp_string("Connected to the server")?; - let bg_matchmaker = matchmaker.background(); - - let rpc_address = format!("http://{}", rpc_address); - // Send intent A - let mut session_send_intent_a = run!( - test, - Bin::Client, - &[ - "intent", - "--node", - &rpc_address, - "--data-path", - intent_a_path_input.to_str().unwrap(), - "--topic", - "asset_v1", - "--signing-key", - BERTHA_KEY, - "--ledger-address", - &validator_one_rpc - ], - Some(40), - )?; - - // means it sent it correctly but not able to gossip it (which is - // correct since there is only 1 node) - session_send_intent_a.exp_string( - "Failed to publish intent in gossiper: InsufficientPeers", - )?; - drop(session_send_intent_a); - - let mut matchmaker = bg_matchmaker.foreground(); - matchmaker.exp_string("trying to match new intent")?; - let bg_matchmaker = matchmaker.background(); - - // Send intent B - let mut session_send_intent_b = run!( - test, - Bin::Client, - &[ - "intent", - "--node", - &rpc_address, - "--data-path", - intent_b_path_input.to_str().unwrap(), - "--topic", - "asset_v1", - "--signing-key", - ALBERT_KEY, - "--ledger-address", - &validator_one_rpc - ], - Some(40), - )?; - - // means it sent it correctly but not able to gossip it (which is - // correct since there is only 1 node) - session_send_intent_b.exp_string( - "Failed to publish intent in gossiper: InsufficientPeers", - )?; - drop(session_send_intent_b); - - let mut matchmaker = bg_matchmaker.foreground(); - matchmaker.exp_string("trying to match new intent")?; - let bg_matchmaker = matchmaker.background(); - - // Send intent C - let mut session_send_intent_c = run!( - test, - Bin::Client, - &[ - "intent", - "--node", - &rpc_address, - "--data-path", - intent_c_path_input.to_str().unwrap(), - "--topic", - "asset_v1", - "--signing-key", - CHRISTEL_KEY, - "--ledger-address", - &validator_one_rpc - ], - Some(40), - )?; - - // means it sent it correctly but not able to gossip it (which is - // correct since there is only 1 node) - session_send_intent_c.exp_string( - "Failed to publish intent in gossiper: InsufficientPeers", - )?; - drop(session_send_intent_c); - - // check that the transfers transactions are correct - let mut matchmaker = bg_matchmaker.foreground(); - matchmaker.exp_string(&format!( - "crafting transfer: {}, {}, 70", - bertha, albert - ))?; - matchmaker.exp_string(&format!( - "crafting transfer: {}, {}, 200", - christel, bertha - ))?; - matchmaker.exp_string(&format!( - "crafting transfer: {}, {}, 100", - albert, christel - ))?; - - // check that the all VPs accept the transaction - let mut ledger = bg_ledger.foreground(); - ledger.exp_string("all VPs accepted transaction")?; - - Ok(()) -} - -fn generate_intent_json( - intent_path: PathBuf, - exchange_json: serde_json::Value, -) { - let intent_writer = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(intent_path) - .unwrap(); - serde_json::to_writer(intent_writer, &exchange_json).unwrap(); -} diff --git a/tests/src/e2e/helpers.rs b/tests/src/e2e/helpers.rs index cc0c45cf8c2..705c8227609 100644 --- a/tests/src/e2e/helpers.rs +++ b/tests/src/e2e/helpers.rs @@ -42,7 +42,7 @@ pub fn find_address(test: &Test, alias: impl AsRef) -> Result
{ Ok(address) } -/// Find the address of the intent gossiper node's RPC endpoint. +/// Find the address of the node's RPC endpoint. pub fn get_actor_rpc(test: &Test, who: &Who) -> String { let base_dir = test.get_base_dir(who); let tendermint_mode = match who { @@ -54,18 +54,6 @@ pub fn get_actor_rpc(test: &Test, who: &Who) -> String { config.ledger.tendermint.rpc_address.to_string() } -/// Find the address of the intent gossiper node's matchmakers server. -pub fn get_gossiper_mm_server(test: &Test, who: &Who) -> String { - let base_dir = test.get_base_dir(who); - let tendermint_mode = match who { - Who::NonValidator => TendermintMode::Full, - Who::Validator(_) => TendermintMode::Validator, - }; - let config = - Config::load(&base_dir, &test.net.chain_id, Some(tendermint_mode)); - config.intent_gossiper.matchmakers_server_addr.to_string() -} - /// Find the address of an account by its alias from the wallet #[allow(dead_code)] pub fn find_keypair( diff --git a/tests/src/e2e/setup.rs b/tests/src/e2e/setup.rs index 6499bf98067..d1df5601084 100644 --- a/tests/src/e2e/setup.rs +++ b/tests/src/e2e/setup.rs @@ -65,21 +65,12 @@ pub fn add_validators(num: u8, mut genesis: GenesisConfig) -> GenesisConfig { let validator_0 = genesis.validator.get_mut("validator-0").unwrap(); // Clone the first validator before modifying it let other_validators = validator_0.clone(); - // Set the first validator to be a bootstrap node to enable P2P connectivity - validator_0.intent_gossip_seed = Some(true); - // A bootstrap node doesn't participate in the gossipsub protocol for - // gossiping intents, so we remove its matchmaker - validator_0.matchmaker_account = None; - validator_0.matchmaker_code = None; - validator_0.matchmaker_tx = None; let net_address_0 = SocketAddr::from_str(validator_0.net_address.as_ref().unwrap()) .unwrap(); let net_address_port_0 = net_address_0.port(); for ix in 0..num { let mut validator = other_validators.clone(); - // Only the first validator is bootstrap - validator.intent_gossip_seed = None; let mut net_address = net_address_0; // 6 ports for each validator let first_port = net_address_port_0 + 6 * (ix as u16 + 1); @@ -769,7 +760,6 @@ pub mod constants { pub const CHRISTEL: &str = "Christel"; pub const CHRISTEL_KEY: &str = "Christel-key"; pub const DAEWON: &str = "Daewon"; - pub const MATCHMAKER_KEY: &str = "matchmaker-key"; // Native VP aliases pub const GOVERNANCE_ADDRESS: &str = "governance"; diff --git a/vm_env/src/intent.rs b/vm_env/src/intent.rs deleted file mode 100644 index 226cb708dbc..00000000000 --- a/vm_env/src/intent.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::collections::HashSet; - -use namada::proto::Signed; -use namada::types::intent; -use namada::types::key::*; - -/// Tx imports and functions. -pub mod tx { - pub use namada::types::intent::*; - - use super::*; - pub fn invalidate_exchange(intent: &Signed) { - use crate::imports::tx; - let key = intent::invalid_intent_key(&intent.data.addr); - let mut invalid_intent: HashSet = - tx::read(&key.to_string()).unwrap_or_default(); - invalid_intent.insert(intent.sig.clone()); - tx::write(&key.to_string(), &invalid_intent) - } -} - -/// Vp imports and functions. -pub mod vp { - pub use namada::types::intent::*; - - use super::*; - - pub fn vp_exchange(intent: &Signed) -> bool { - use crate::imports::vp; - let key = intent::invalid_intent_key(&intent.data.addr); - - let invalid_intent_pre: HashSet = - vp::read_pre(&key.to_string()).unwrap_or_default(); - let invalid_intent_post: HashSet = - vp::read_post(&key.to_string()).unwrap_or_default(); - !invalid_intent_pre.contains(&intent.sig) - && invalid_intent_post.contains(&intent.sig) - } -} diff --git a/vm_env/src/lib.rs b/vm_env/src/lib.rs index 578079d695c..0da9ae9804b 100644 --- a/vm_env/src/lib.rs +++ b/vm_env/src/lib.rs @@ -9,7 +9,6 @@ pub mod governance; pub mod ibc; pub mod imports; -pub mod intent; pub mod key; pub mod nft; pub mod proof_of_stake; @@ -29,7 +28,6 @@ pub mod tx_prelude { pub use crate::governance::tx as governance; pub use crate::ibc::{Ibc, IbcActions}; pub use crate::imports::tx::*; - pub use crate::intent::tx as intent; pub use crate::nft::tx as nft; pub use crate::proof_of_stake::{self, PoS, PosRead, PosWrite}; pub use crate::token::tx as token; @@ -48,7 +46,6 @@ pub mod vp_prelude { pub use namada_macros::validity_predicate; pub use crate::imports::vp::*; - pub use crate::intent::vp as intent; pub use crate::key::vp as key; pub use crate::nft::vp as nft; pub use crate::token::vp as token; diff --git a/wasm/checksums.json b/wasm/checksums.json index 898f6e97634..e222bd6aef1 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,19 +1,19 @@ { - "tx_bond.wasm": "tx_bond.16097490afa7378c79e6216751b20796cde3a9026c34255c3f1e5ec5a4c9482e.wasm", - "tx_from_intent.wasm": "tx_from_intent.f8d1937b17a3abaf7ea595526c870b3d57ddef8e0c1bc96f8e0a448864b186c7.wasm", - "tx_ibc.wasm": "tx_ibc.378b10551c0b22c2c892d24e2676ee5160d654e2e53a50e7925e0f2c6321497b.wasm", - "tx_init_account.wasm": "tx_init_account.adab66c2b4d635e9c42133936aafb143363f91dddff2a60f94df504ffec951a6.wasm", - "tx_init_nft.wasm": "tx_init_nft.d1065ebd80ba6ea97f29bc2268becf9ba3ba2952641992464f3e9e868df17447.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.184131576a579f9ece96460d1eb20e5970fcd149b0527c8e56b711e5c535aa5f.wasm", - "tx_init_validator.wasm": "tx_init_validator.2990747d24d467b56e19724c5d13df826a3aab83f7e1bf26558dbdf44e260f8a.wasm", - "tx_mint_nft.wasm": "tx_mint_nft.33db14dea4a03ff7508ca44f3ae956d83c0abceb3dae5be844668e54ac22b273.wasm", - "tx_transfer.wasm": "tx_transfer.a601d62296f56f6b4dabb0a2ad082478d195e667c7469f363bdfd5fe41349bd8.wasm", - "tx_unbond.wasm": "tx_unbond.014cbf5b0aa3ac592c0a6940dd502ec8569a3af4d12782e3a5931c15dc13042f.wasm", - "tx_update_vp.wasm": "tx_update_vp.83d4caeb5a9ca3009cd899810493a6b87b4c07fa9ed36f297db99dc881fb9a1c.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.bcb5280be9dfeed0a7650ba5e4a3cebc2c19b76780fd74dcb345be3da766b64a.wasm", - "tx_withdraw.wasm": "tx_withdraw.8fc0a3439ee9ae66047c520519877bc1f540e0cb02abfa31afa8cce8cd069b6f.wasm", - "vp_nft.wasm": "vp_nft.2c820c728d241b82bf0ed3c552ee9e7c046bceaa4f7b6f12d3236a1a3d7c1589.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.6e762f3fda8aa7a252e2b29a4a312db91ded062d6c18b8b489883733c89dc227.wasm", - "vp_token.wasm": "vp_token.c45cc3848f12fc47713702dc206d1312ad740a6bbee7f141556714f6f89d4985.wasm", - "vp_user.wasm": "vp_user.d6cd2f4b5bc26f96df6aa300fddf4d25e1656920d59896209bd54ae8d407ecde.wasm" + "tx_bond.wasm": "tx_bond.3955960def0f45b2c7eda810354716b29cf7063891cf23bf001f067220b348a5.wasm", + "tx_from_intent.wasm": "tx_from_intent.e21563260c03cfdab1f195878f49bf93722027ad26fcd097cfebbc5c4d279082.wasm", + "tx_ibc.wasm": "tx_ibc.1b6ee957fb5a8ad75bdbdf5435014dcd1b9bc4dc0d749d9401a9814ddaf4c55a.wasm", + "tx_init_account.wasm": "tx_init_account.273fadc04419989eaecdbcce8efac0ee40223f1850c55a29228afd6fa5e0abce.wasm", + "tx_init_nft.wasm": "tx_init_nft.2ef0c7cb42266494a37c5de05cf912eca777c76f8cedbe1164f13cbaaf490cd9.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.c6426e5f9bc06c01f331f8399f69c131287c707a33e78d8c8c57dfce435d9150.wasm", + "tx_init_validator.wasm": "tx_init_validator.dde9e2b6f7bea6e56326667becc97a3ab863a15a44528550536922bb4550cba2.wasm", + "tx_mint_nft.wasm": "tx_mint_nft.db1c11ed264dcce8b0a3218cecabc4af8832a22891d9c67fa6f92be78fa861fb.wasm", + "tx_transfer.wasm": "tx_transfer.6deab964149869ec638777a344c5fb1ad486c4f44c731d89793d5940fc3d8714.wasm", + "tx_unbond.wasm": "tx_unbond.57286cab933765181af77672fad7f69c373708e459a01d48631f549c693399b9.wasm", + "tx_update_vp.wasm": "tx_update_vp.dd4b87f25b3d866ef6a7c30ea3cba743e2c011fa5c44ece7a53cff6ad682d975.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.a18464e5966177552fc237c07111bbdd0d70c2940e5e761b2f80c217f4fa32db.wasm", + "tx_withdraw.wasm": "tx_withdraw.fe25543edec0ef74eadcd1de2f354e32002f8a252e4232ed2be4e0340675646f.wasm", + "vp_nft.wasm": "vp_nft.70446e909b233f60beda248085d7de9ba7822d81e580e220bda28764975ace54.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.af177f0935c903c8b5c49305b759e48131cbf8032b6d409216ee74a12a6903b2.wasm", + "vp_token.wasm": "vp_token.3511bed65a7c98fea300cebafed28623ba776da488d06e285f0bf168d4bf1fdf.wasm", + "vp_user.wasm": "vp_user.5748f41419ac1b2eab918ffbe4e7f68125e1cdfe9537ffbcbcc2785c3030d0dd.wasm" } \ No newline at end of file diff --git a/wasm/wasm_source/src/lib.rs b/wasm/wasm_source/src/lib.rs index 3a674ad97bc..89299927548 100644 --- a/wasm/wasm_source/src/lib.rs +++ b/wasm/wasm_source/src/lib.rs @@ -1,7 +1,5 @@ #[cfg(feature = "tx_bond")] pub mod tx_bond; -#[cfg(feature = "tx_from_intent")] -pub mod tx_from_intent; #[cfg(feature = "tx_ibc")] pub mod tx_ibc; #[cfg(feature = "tx_init_account")] diff --git a/wasm/wasm_source/src/tx_from_intent.rs b/wasm/wasm_source/src/tx_from_intent.rs deleted file mode 100644 index e39963fae71..00000000000 --- a/wasm/wasm_source/src/tx_from_intent.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! A tx for a token transfer crafted by matchmaker from intents. -//! This tx uses `intent::IntentTransfers` wrapped inside -//! `SignedTxData` as its input as declared in `shared` crate. - -use namada_tx_prelude::*; - -#[transaction] -fn apply_tx(tx_data: Vec) { - let signed = SignedTxData::try_from_slice(&tx_data[..]).unwrap(); - - let tx_data = - intent::IntentTransfers::try_from_slice(&signed.data.unwrap()[..]); - - let tx_data = tx_data.unwrap(); - - // make sure that the matchmaker has to validate this tx - insert_verifier(&tx_data.source); - - for token::Transfer { - source, - target, - token, - amount, - } in tx_data.matches.transfers - { - token::transfer(&source, &target, &token, amount); - } - - tx_data - .matches - .exchanges - .values() - .into_iter() - .for_each(intent::invalidate_exchange); -} diff --git a/wasm/wasm_source/src/vp_user.rs b/wasm/wasm_source/src/vp_user.rs index a222a344efd..fbd606b1827 100644 --- a/wasm/wasm_source/src/vp_user.rs +++ b/wasm/wasm_source/src/vp_user.rs @@ -6,24 +6,15 @@ //! It allows to bond, unbond and withdraw tokens to and from PoS system with a //! valid signature. //! -//! It allows to fulfil intents that were signed by this account's key if they -//! haven't already been fulfilled (fulfilled intents are added to the owner's -//! invalid intent set). -//! //! Any other storage key changes are allowed only with a valid signature. -use namada_vp_prelude::intent::{ - Exchange, FungibleTokenIntent, IntentTransfers, -}; use namada_vp_prelude::storage::KeySeg; use namada_vp_prelude::*; use once_cell::unsync::Lazy; -use rust_decimal::prelude::*; enum KeyType<'a> { Token(&'a Address), PoS, - InvalidIntentSet(&'a Address), Nft(&'a Address), Vp(&'a Address), GovernanceVote(&'a Address), @@ -36,8 +27,6 @@ impl<'a> From<&'a storage::Key> for KeyType<'a> { Self::Token(address) } else if proof_of_stake::is_pos_key(key) { Self::PoS - } else if let Some(address) = intent::is_invalid_intent_key(key) { - Self::InvalidIntentSet(address) } else if let Some(address) = nft::is_nft_key(key) { Self::Nft(address) } else if gov_storage::is_vote_key(key) { @@ -83,11 +72,6 @@ fn validate_tx( _ => false, }); - let valid_intent = Lazy::new(|| match &*signed_tx_data { - Ok(signed_tx_data) => check_intent_transfers(&addr, signed_tx_data), - _ => false, - }); - if !is_tx_whitelisted() { return false; } @@ -103,14 +87,13 @@ fn validate_tx( read_post(&key).unwrap_or_default(); let change = post.change() - pre.change(); // debit has to signed, credit doesn't - let valid = change >= 0 || *valid_sig || *valid_intent; + let valid = change >= 0 || *valid_sig; debug_log!( - "token key: {}, change: {}, valid_sig: {}, \ - valid_intent: {}, valid modification: {}", + "token key: {}, change: {}, valid_sig: {}, valid \ + modification: {}", key, change, *valid_sig, - *valid_intent, valid ); valid @@ -148,27 +131,6 @@ fn validate_tx( ); valid } - KeyType::InvalidIntentSet(owner) => { - if owner == &addr { - let key = key.to_string(); - let pre: HashSet = - read_pre(&key).unwrap_or_default(); - let post: HashSet = - read_post(&key).unwrap_or_default(); - // A new invalid intent must have been added - pre.len() + 1 == post.len() - } else { - debug_log!( - "This address ({}) is not of owner ({}) of \ - InvalidIntentSet key: {}", - addr, - owner, - key - ); - // If this is not the owner, allow any change - true - } - } KeyType::Nft(owner) => { if owner == &addr { *valid_sig @@ -218,148 +180,6 @@ fn validate_tx( true } -fn check_intent_transfers( - addr: &Address, - signed_tx_data: &SignedTxData, -) -> bool { - if let Some((raw_intent_transfers, exchange, intent)) = - try_decode_intent(addr, signed_tx_data) - { - log_string("check intent"); - return check_intent(addr, exchange, intent, raw_intent_transfers); - } - false -} - -fn try_decode_intent( - addr: &Address, - signed_tx_data: &SignedTxData, -) -> Option<( - Vec, - namada_vp_prelude::Signed, - namada_vp_prelude::Signed, -)> { - let raw_intent_transfers = signed_tx_data.data.as_ref().cloned()?; - let mut tx_data = - IntentTransfers::try_from_slice(&raw_intent_transfers[..]).ok()?; - debug_log!( - "tx_data.matches.exchanges: {:?}, {}", - tx_data.matches.exchanges, - &addr - ); - if let (Some(exchange), Some(intent)) = ( - tx_data.matches.exchanges.remove(addr), - tx_data.matches.intents.remove(addr), - ) { - return Some((raw_intent_transfers, exchange, intent)); - } else { - log_string("no intent with a matching address"); - } - None -} - -fn check_intent( - addr: &Address, - exchange: namada_vp_prelude::Signed, - intent: namada_vp_prelude::Signed, - raw_intent_transfers: Vec, -) -> bool { - // verify signature - let pk = key::get(addr); - if let Some(pk) = pk { - if intent.verify(&pk).is_err() { - log_string("invalid sig"); - return false; - } - } else { - return false; - } - - // verify the intent have not been already used - if !intent::vp_exchange(&exchange) { - return false; - } - - // verify the intent is fulfilled - let Exchange { - addr, - token_sell, - rate_min, - token_buy, - min_buy, - max_sell, - vp, - } = &exchange.data; - - debug_log!("vp is: {}", vp.is_some()); - - if let Some(code) = vp { - let eval_result = eval(code.to_vec(), raw_intent_transfers); - debug_log!("eval result: {}", eval_result); - if !eval_result { - return false; - } - } - - debug_log!( - "exchange description: {}, {}, {}, {}, {}", - token_sell, - token_buy, - max_sell.change(), - min_buy.change(), - rate_min.0 - ); - - let token_sell_key = token::balance_key(token_sell, addr).to_string(); - let mut sell_difference: token::Amount = - read_pre(&token_sell_key).unwrap_or_default(); - let sell_post: token::Amount = - read_post(token_sell_key).unwrap_or_default(); - - sell_difference.spend(&sell_post); - - let token_buy_key = token::balance_key(token_buy, addr).to_string(); - let buy_pre: token::Amount = read_pre(&token_buy_key).unwrap_or_default(); - let mut buy_difference: token::Amount = - read_post(token_buy_key).unwrap_or_default(); - - buy_difference.spend(&buy_pre); - - let sell_diff: Decimal = sell_difference.change().into(); // -> how many token I sold - let buy_diff: Decimal = buy_difference.change().into(); // -> how many token I got - - debug_log!( - "buy_diff > 0: {}, rate check: {}, max_sell > sell_diff: {}, buy_diff \ - > min_buy: {}", - buy_difference.change() > 0, - buy_diff / sell_diff >= rate_min.0, - max_sell.change() >= sell_difference.change(), - buy_diff >= min_buy.change().into() - ); - - if !(buy_difference.change() > 0 - && (buy_diff / sell_diff >= rate_min.0) - && max_sell.change() >= sell_difference.change() - && buy_diff >= min_buy.change().into()) - { - debug_log!( - "invalid exchange, {} / {}, sell diff: {}, buy diff: {}, \ - max_sell: {}, rate_min: {}, min_buy: {}, buy_diff / sell_diff: {}", - token_sell, - token_buy, - sell_difference.change(), - buy_difference.change(), - max_sell.change(), - rate_min.0, - min_buy.change(), - buy_diff / sell_diff - ); - false - } else { - true - } -} - #[cfg(test)] mod tests { use address::testing::arb_non_internal_address; diff --git a/wasm_for_tests/wasm_source/Cargo.lock b/wasm_for_tests/wasm_source/Cargo.lock index 9df5195b2f1..876455fcaaf 100644 --- a/wasm_for_tests/wasm_source/Cargo.lock +++ b/wasm_for_tests/wasm_source/Cargo.lock @@ -1357,7 +1357,7 @@ dependencies = [ [[package]] name = "libsecp256k1" version = "0.7.0" -source = "git+https://github.com/brentstone/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" +source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" dependencies = [ "arrayref", "base64", @@ -1373,7 +1373,7 @@ dependencies = [ [[package]] name = "libsecp256k1-core" version = "0.3.0" -source = "git+https://github.com/brentstone/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" +source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" dependencies = [ "crunchy", "digest 0.9.0", @@ -1383,7 +1383,7 @@ dependencies = [ [[package]] name = "libsecp256k1-gen-ecmult" version = "0.3.0" -source = "git+https://github.com/brentstone/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" +source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" dependencies = [ "libsecp256k1-core", ] @@ -1391,7 +1391,7 @@ dependencies = [ [[package]] name = "libsecp256k1-gen-genmult" version = "0.3.0" -source = "git+https://github.com/brentstone/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" +source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" dependencies = [ "libsecp256k1-core", ] @@ -1527,7 +1527,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "namada" -version = "0.7.0" +version = "0.7.1" dependencies = [ "ark-bls12-381", "ark-serialize", @@ -1576,7 +1576,7 @@ dependencies = [ [[package]] name = "namada_macros" -version = "0.7.0" +version = "0.7.1" dependencies = [ "quote", "syn", @@ -1584,7 +1584,7 @@ dependencies = [ [[package]] name = "namada_proof_of_stake" -version = "0.7.0" +version = "0.7.1" dependencies = [ "borsh", "proptest", @@ -1593,7 +1593,7 @@ dependencies = [ [[package]] name = "namada_tests" -version = "0.7.0" +version = "0.7.1" dependencies = [ "chrono", "concat-idents", @@ -1611,7 +1611,7 @@ dependencies = [ [[package]] name = "namada_tx_prelude" -version = "0.7.0" +version = "0.7.1" dependencies = [ "namada_vm_env", "sha2 0.10.2", @@ -1619,7 +1619,7 @@ dependencies = [ [[package]] name = "namada_vm_env" -version = "0.7.0" +version = "0.7.1" dependencies = [ "borsh", "hex", @@ -1629,7 +1629,7 @@ dependencies = [ [[package]] name = "namada_vp_prelude" -version = "0.7.0" +version = "0.7.1" dependencies = [ "namada_vm_env", "sha2 0.10.2", @@ -1637,7 +1637,7 @@ dependencies = [ [[package]] name = "namada_wasm_for_tests" -version = "0.7.0" +version = "0.7.1" dependencies = [ "borsh", "getrandom",