Compare commits

...

27 Commits

  1. 201
      Cargo.lock
  2. 13
      Cargo.toml
  3. 36
      README.md
  4. BIN
      README.pdf
  5. 55
      src/crypto.rs
  6. 1
      src/error.rs
  7. 96
      src/ironforce.rs
  8. 161
      src/lib.rs
  9. 117
      src/message.rs
  10. 101
      src/transport.rs
  11. 87
      src/tunnel.rs
  12. 8
      src/way.rs
  13. 8
      src/ways/mod.rs

201
Cargo.lock generated

@ -1,15 +1,18 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "as-slice"
version = "0.1.3"
name = "ahash"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.7.3"
@ -39,11 +42,42 @@ name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clear_on_drop"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random-macro"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "curve25519-dalek"
version = "2.0.0"
@ -65,25 +99,15 @@ dependencies = [
]
[[package]]
name = "ecdsa"
version = "0.5.0-pre"
name = "ed25519-dalek"
version = "1.0.0-pre.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"elliptic-curve 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"signature 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "elliptic-curve"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -99,14 +123,6 @@ dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
@ -118,21 +134,12 @@ dependencies = [
]
[[package]]
name = "hash32"
version = "0.1.1"
name = "hashbrown"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heapless"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"as-slice 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hash32 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -140,13 +147,13 @@ dependencies = [
name = "ironforest"
version = "0.1.0"
dependencies = [
"curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ecdsa 0.5.0-pre (registry+https://github.com/rust-lang/crates.io-index)",
"heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"postcard 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pinecone 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"x25519-dalek 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -160,25 +167,28 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "postcard"
version = "0.4.3"
name = "pinecone"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"postcard-cobs 0.1.5-pre (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "postcard-cobs"
version = "0.1.5-pre"
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
name = "proc-macro-hack"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
@ -233,6 +243,15 @@ dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_os"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.104"
@ -262,19 +281,6 @@ dependencies = [
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "signature"
version = "1.0.0-pre.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "subtle"
version = "2.2.2"
@ -290,6 +296,17 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typenum"
version = "1.11.2"
@ -305,47 +322,75 @@ name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "x25519-dalek"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zeroize"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zeroize_derive"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum as-slice 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70"
"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a"
"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a"
"checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum ecdsa 0.5.0-pre (registry+https://github.com/rust-lang/crates.io-index)" = "1d7e523a6e90b7682c0857c1d26cf06f3a0224bc2dfb0766f5e35a0a71ad3dbe"
"checksum elliptic-curve 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01f69be7d1feb7a7a04f158aaf32c7deaa7604e9bd58145525e536438c4e5096"
"checksum ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)" = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum hash32 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
"checksum heapless 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10b591a0032f114b7a77d4fbfab452660c553055515b7d7ece355db080d19087"
"checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum postcard 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f61f42c9617f3d7b447ee300bf80cb16c7cd7b28ca88555822793f073f69719f"
"checksum postcard-cobs 0.1.5-pre (registry+https://github.com/rust-lang/crates.io-index)" = "7c68cb38ed13fd7bc9dd5db8f165b7c8d9c1a315104083a2b10f11354c2af97f"
"checksum pinecone 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d428731d3fa65fb4be3a898fa9dc46f512b43874a621377d21c96582f1372e21"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro-hack 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f918f2b601f93baa836c1c2945faef682ba5b6d4828ecb45eeb7cc3c71b811b4"
"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
"checksum signature 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)" = "561619c00cf6a187ebfc21e46bc4c0ce4e4d5f67cd640e7b1c58d9c3754b38aa"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941"
"checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum x25519-dalek 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217"
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"

13
Cargo.toml

@ -5,11 +5,16 @@ authors = ["ennucore <ennucore@gmail.com>"]
edition = "2018"
[features]
default = []
std = []
[dependencies]
ecdsa = "0.5.0-pre"
curve25519-dalek = "2"
rand_os = "0.2.2"
x25519-dalek = "0.6.0"
ed25519-dalek = { version = "1.0.0-pre.3", features = ["serde"] }
sha2 = "0.8.1"
rand = "*"
serde = { version = "1.0", features = ["derive", "alloc"], default-features = false }
postcard = "0.4.3"
heapless = "0.5.3"
pinecone = "0.2.3"

36
README.md

@ -6,9 +6,11 @@ __IronForest__ _(IF)_ is a decentralized P2P network.
IronForest hardware network has two types of devices: digital (IronForest Digital Device, IFDD) and analog (IronForest Digital Device, IFAD)
## IronForest tonnels
_The following description is meant to be read in Typora_
Devices communicate through tonnels. Tonnel is a list of IF nodes' IDs: $ T(a_1, a_n)=[a_1, a_2, \,..., \, a_n] $, where $a_i$ is an id. _Short tonnel_ ($s(T)$) is one of the $min\_tonnels$ shortest paths (by time) between two nodes. Each IF node $X$ has its own list of short tonnels $X.TT$ ($\forall \, T \in X.TT\,\, X\in T$). It is obvious, that if $T(a_1, a_n)_p=A$ and $T(a_1, a_n)_q=B$ , then $T(A, B)=T(a_1,a_n)_{p:q}$. Therefore, if node $X$ has ID of node $Y$ somewhere in its list of tonnels, it knows a tonnel to $Y$.
## IronForest tunnels
Devices communicate through tunnels. tunnel is a list of IF nodes' IDs: $ T(a_1, a_n)=[a_1, a_2, \,..., \, a_n] $, where $a_i$ is an id. _Short tunnel_ ($s(T)$) is one of the $min\_tunnels$ shortest paths (by time) between two nodes. Each IF node $X$ has its own list of short tunnels $X.TT$ ($\forall \, T \in X.TT\,\, X\in T$). It is obvious, that if $T(a_1, a_n)_p=A$ and $T(a_1, a_n)_q=B$ , then $T(A, B)=T(a_1,a_n)_{p:q}$. Therefore, if node $X$ has ID of node $Y$ somewhere in its list of tunnels, it knows a tunnel to $Y$.
```mermaid
graph TD;
@ -17,28 +19,28 @@ A---G---B;
E---Z---F;
```
_Here [A, G, B], [A, E, F, B], [A, E, Z, F, B] are tonnels from A to B, but the last one will not probably be short tonnel, because it will highly likely take more time for a packet to reach the $B$ node by this path._
_Here [A, G, B], [A, E, F, B], [A, E, Z, F, B] are tunnels from A to B, but the last one will not probably be short tunnel, because it will highly likely take more time for a packet to reach the $B$ node by this path._
Node $N$ is _known_ to node $B$ if node $B$ has node $N$ in its list of tonnels: $kn(N, B)=\exists T \in N.TT\,:\,B\in T$.
Node $N$ is _known_ to node $B$ if node $B$ has node $N$ in its list of tunnels: $kn(N, B)=\exists T \in N.TT\,:\,B\in T$.
On low-level, a also tonnel has its frequency $T.F$: IFADs retranslate signals on all frequencies from $F_2 \cup \{F_1\}$ and IFDDs set one of their transmitters to the $T.F$ frequency.
On low-level, a also tunnel has its frequency $T.F$: IFADs retranslate signals on all frequencies from $F_2 \cup \{F_1\}$ and IFDDs set one of their transmitters to the $T.F$ frequency.
#### Building a tonnel
#### Building a tunnel
How does node $A$ build a tonnel to an unknown node $B$?
How does node $A$ build a tunnel to an unknown node $B$?
$A$ sends a multicast message to the network. This message consists of type (tonnel request), destination $m.d=B$ and path (list) $m.P$ ($P_0=[A]$) and tonnel (empty for now). When another node $N$ receives message of this type, it appends its id to the path ($m.P+=[N]$) and resends this message either nobody if $N$ is a part of too much tonnels (this number is equal to the number of $F2$ radio modules on the IFDD board) either to all available nodes if node $B$ is not a known node to $N$ (if $!kn(N, B) = \nexists T \in N.TT: B\in T$) and message has no tonnel parameter either only to some nodes. Let's see the second variant more detailed.
$A$ sends a multicast message to the network. This message consists of type (tunnel request), destination $m.d=B$ and path (list) $m.P$ ($P_0=[A]$) and tunnel (empty for now). When another node $N$ receives message of this type, it appends its id to the path ($m.P+=[N]$) and resends this message either nobody if $N$ is a part of too much tunnels (this number is equal to the number of $F2$ radio modules on the IFDD board) either to all available nodes if node $B$ is not a known node to $N$ (if $!kn(N, B) = \nexists T \in N.TT: B\in T$) and message has no tunnel parameter either only to some nodes. Let's see the second variant more detailed.
So, node $N$ receives a message $m$. If message has not empty tonnel parameter $m.T$, then $N$ remembers tonnel T, sends message to the next node in the tonnel ($m.T_{k+1}, k: m.T_k = N$). If node $B$($m.d$) is known to $N$ ($kn(N, B)$), then:
So, node $N$ receives a message $m$. If message has not empty tunnel parameter $m.T$, then $N$ remembers tunnel T, sends message to the next node in the tunnel ($m.T_{k+1}, k: m.T_k = N$). If node $B$($m.d$) is known to $N$ ($kn(N, B)$), then:
1. $N$ checks if number of tonnels to $B$ is enough: $TT_2=\{T \in N.TT: B \in T\},\,\,|TT_2|>= tonnel\_num$, if not, then message is resent through all paths
2. $N$ sends message $m$ to $tonnel\_num$ of $TT_2$ ($TT_{2\,[1:tonnel\_num]}$)
1. $N$ checks if number of tunnels to $B$ is enough: $TT_2=\{T \in N.TT: B \in T\},\,\,|TT_2|>= tunnel\_num$, if not, then message is resent through all paths
2. $N$ sends message $m$ to $tunnel\_num$ of $TT_2$ ($TT_{2\,[1:tunnel\_num]}$)
$M=[m_1, \,...,\,m_{tonnel\_num}]$ is a list of first $tonnel\_num$ messages that reached B
$M=[m_1, \,...,\,m_{tunnel\_num}]$ is a list of first $tunnel\_num$ messages that reached B
When message $m_i \in M$ with updated path reaches $B$, $B$ remembers reversed of $m_i.P$ as the tonnel from $B$ to $A$: $T(A, B)=m.P$. $B$ decides frequency $T.F$ of tonnel (for hardware network). It sends a message with this frequency. to $A$ as multicast message using this tonnel. $A$ receives this tonnel and remembers it. Now $kn(A, B) \and kn(B, A)$.
When message $m_i \in M$ with updated path reaches $B$, $B$ remembers reversed of $m_i.P$ as the tunnel from $B$ to $A$: $T(A, B)=m.P$. $B$ decides frequency $T.F$ of tunnel (for hardware network). It sends a message with this frequency. to $A$ as multicast message using this tunnel. $A$ receives this tunnel and remembers it. Now $kn(A, B) \and kn(B, A)$.
## IronForest Hardware Network
@ -46,7 +48,7 @@ There are two types of IFHN devices: analog devices (IFAD) and digital (IFDD). T
IronForest hardware0 network has two frequencies: one (_F1_) for multicast and a frequency range (F2) for tonnels.
IronForest hardware0 network has two frequencies: one (_F1_) for multicast and a frequency range (F2) for tunnels.
## IronForest analog device (IFAD) description
@ -65,11 +67,7 @@ Digital device receives signal, amplifies it and demodulates. Then signal is pro
3. If this is an $F2$ signal, check if it needs resending by this IFDD, resend by radio and overlays if needed
4. If this is an $F1$ signal, process it and resend by radio and overlays
IFDD's MC has a list of known tonnels. If it is clear that the destination of a packet is a known node (known as a part of a tonnel), IFDD will not send packet to all available nodes, it will send it just like through a usual tonnel to this known node.
## Calculating network speed and price for square kilometer
_todo_
IFDD's MC has a list of known tunnels. If it is clear that the destination of a packet is a known node (known as a part of a tunnel), IFDD will not send packet to all available nodes, it will send it just like through a usual tunnel to this known node.

BIN
README.pdf

Binary file not shown.

55
src/crypto.rs

@ -1,31 +1,56 @@
extern crate rand;
extern crate ed25519_dalek;
use ed25519_dalek::{PublicKey as PK, Keypair, Signature};
use serde::{Serialize, Deserialize};
use rand::rngs::OsRng;
use alloc::vec::Vec;
use crate::message::Sign;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct PublicKey {
pub id: u64
pub key: [u8; 32]
}
impl PublicKey {
pub fn verify_sign(&self, raw: &Vec<u8>, sign: &Vec<u8>) -> bool {
PK::from_bytes(&self.key).unwrap()
.verify(
raw,
&Signature::from_bytes(sign.clone().into_boxed_slice().as_ref()).unwrap(),
).is_ok()
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct KeyPack {
pub public_key: PublicKey,
secret_key: u64,
pub struct Keys {
pub pair: Keypair,
}
impl KeyPack {
pub fn gen() -> KeyPack {
KeyPack { public_key: PublicKey { id: rand::random::<u64>() }, secret_key: 0 }
impl Keys {
pub fn gen() -> Keys {
Keys { pair: Keypair::generate(&mut OsRng {}) }
}
}
impl PublicKey {
pub fn verify_sign(self, sign: u64) -> bool {
true
pub fn verify_sign(msg: &crate::message::Message) -> bool {
match &msg.clone().sign {
Sign::NoSign => true,
Sign::Signed(key, sign) => {
key.verify_sign(&msg.get_hash(), sign)
}
}
}
impl KeyPack {
pub fn sign(self, msg: u64) -> u64 {
0
impl Keys {
pub fn sign(&self, content: &Vec<u8>) -> Vec<u8> {
self.pair.sign(content.as_ref()).to_bytes().to_vec()
}
pub fn get_public(&self) -> PublicKey {
PublicKey { key: *self.clone().pair.public.as_bytes() }
}
}

1
src/error.rs

@ -1 +0,0 @@
pub trait Error {}

96
src/ironforce.rs

@ -1,14 +1,102 @@
use crate::transport::Transport;
use crate::crypto::{PublicKey, KeyPack};
use crate::crypto::{PublicKey, Keys};
use crate::message::{Message, MsgType};
use crate::tunnel::Tunnel;
use alloc::vec::Vec;
const UNICAST_TUNNELS: u32 = 2;
const MULTICAST_TUNNELS: u32 = 5;
pub struct IronForce {
transport: Transport,
key_pack: KeyPack
tunnels: Vec<Tunnel>,
pub key_pack: Keys,
}
impl IronForce {
pub fn gen() -> IronForce {
IronForce { transport: Transport {}, key_pack: KeyPack::gen() }
pub fn new() -> IronForce {
IronForce { transport: Transport::new(), tunnels: Vec::<Tunnel>::new(), key_pack: Keys::gen() }
}
fn is_valid_message(&self, msg: &Message) -> bool {
// todo: some kind of PoW
msg.verify()
}
pub fn new_message(&self, msg_type: MsgType, body: &Vec<u8>) -> Message {
Message::new(msg_type, body.clone(), &self.key_pack)
}
fn send_through_tunnel_to(&self, msg: &Message, tunnel: &Tunnel, to: &PublicKey) {
self.transport.send_to(msg, &tunnel.next(&self.key_pack.get_public(), &to).unwrap());
}
fn service_msg(&self, body: &Vec<u8>) {
let msg = self.new_message(MsgType::Service, body);
for tunnel in &self.tunnels {
match tunnel.get_next(&self.key_pack.get_public(), true) {
Some(next_forward) => {self.send_through_tunnel_to(&msg, tunnel, &next_forward)}
None => {}
}
match tunnel.get_next(&self.key_pack.get_public(), false) {
Some(next_backwards) => {self.send_through_tunnel_to(&msg, tunnel, &next_backwards)}
None => {}
}
}
}
pub fn multicast(&self, msg: &Message) -> u32 {
let mut count = 0;
for tunnel in &self.tunnels {
for node in tunnel.next_nodes(&self.key_pack.get_public()) {
count += 1;
self.send_through_tunnel_to(msg, tunnel, &node)
}
if count == MULTICAST_TUNNELS {
break
}
}
count
}
pub fn send_message_to(&self, msg: &Message, to: PublicKey) -> u32 {
let mut count = 0;
for tunnel in &self.tunnels {
if tunnel.is_in_tunnel(&to) {
count += 1;
self.send_through_tunnel_to(msg, tunnel, &to)
}
if count == UNICAST_TUNNELS {
break;
}
}
if count == 0 {
// todo: send service message and create new tunnel
}
count
}
fn handle_message(&self, msg: &Message) {
if self.is_valid_message(msg) {
match &msg.content.msg_type {
MsgType::Service => {
self.service_msg(&msg.content.body)
}
MsgType::MultiCast => {
self.multicast(msg);
}
MsgType::UniCast(target) => {
let tunnel = match &msg.tunnel {
crate::message::MsgTunnel::Tunnel(t) => t,
crate::message::MsgTunnel::NoTunnel => panic!()
};
self.send_through_tunnel_to(msg, tunnel, target)
}
}
}
}
}

161
src/lib.rs

@ -1,30 +1,165 @@
#![feature(alloc)]
#![no_std]
#![allow(dead_code)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
mod ironforce;
mod transport;
mod message;
mod crypto;
mod error;
mod way;
mod tunnel;
#[cfg(feature = "std")]
mod ways;
#[cfg(test)]
mod tests {
use crate::ironforce::IronForce;
use crate::message::{MsgType, Message};
use heapless::{Vec, consts::*};
mod iron_force {
use crate::ironforce::IronForce;
use crate::message::{Message, MsgType};
#[test]
fn creation_works() {
IronForce::gen();
use alloc::vec::Vec;
#[test]
fn creation() {
IronForce::new();
}
#[test]
fn new_message() {
let mut iforce = IronForce::new();
assert_eq!(
iforce.new_message(
MsgType::Service, &Vec::<u8>::new(),
),
Message::new(MsgType::Service, Vec::<u8>::new(), &iforce.key_pack)
);
}
}
mod crypto {
use crate::crypto::{PublicKey, Keys, verify_sign};
#[test]
fn creation() {
let key_pair = Keys::gen();
}
#[test]
fn signing() {
let key_pair = Keys::gen();
key_pair.sign(&[1u8; 129].to_vec());
}
#[test]
fn verification() {
let key_pair = Keys::gen();
let sign = key_pair.sign(&[1u8; 129].to_vec());
assert!(key_pair.get_public().verify_sign(&[1u8; 129].to_vec(), &sign));
assert!(!key_pair.get_public().verify_sign(&[0u8; 129].to_vec(), &sign));
assert!(!key_pair.get_public().verify_sign(&[1u8; 129].to_vec(), &[0u8; 64].to_vec()));
}
}
#[test]
fn serialization() {
let msg = crate::message::Message::new(MsgType::MultiCast, Vec::<u8, U11>::new(), crate::crypto::KeyPack::gen());
let serialized = msg.ser();
let msg2 = Message::deserialize(serialized);
mod message {
use crate::message::{MsgType, Message};
use crate::crypto::Keys;
use alloc::vec::Vec;
#[test]
fn serialization() {
let key_pack = Keys::gen();
let msg = Message::new(
MsgType::MultiCast, Vec::<u8>::new(), &key_pack,
);
let serialized = &msg.ser();
let msg2 = Message::deserialize(serialized.to_vec());
assert_eq!(msg2.content.msg_type, MsgType::MultiCast);
}
#[test]
fn valid_message_creation() {
let msg = Message::new(
MsgType::MultiCast, Vec::<u8>::new(), &Keys::gen(),
);
assert!(&msg.verify());
}
#[test]
fn invalid_sign() {
let key_pack = Keys::gen();
let mut msg = Message::new(
MsgType::MultiCast, Vec::<u8>::new(), &key_pack,
);
msg.sign = crate::message::Sign::Signed(key_pack.get_public(), [0; 64].to_vec());
assert!(!&msg.verify());
msg.hash = [0; 64].to_vec();
msg.sign = crate::message::Sign::Signed(
key_pack.get_public(),
key_pack.sign(&msg.content_hash),
);
assert!(!&msg.verify());
}
#[test]
fn test_hash() {
let msg = Message::new(
MsgType::MultiCast, Vec::<u8>::new(), &crate::crypto::Keys::gen(),
);
msg.get_hash();
}
}
mod tunnel {
use crate::tunnel::Tunnel;
use crate::crypto::PublicKey;
fn key(i: u8) -> PublicKey {
PublicKey { key: [i; 32] }
}
fn create_test_tunnel() -> Tunnel {
Tunnel::from_vec([
key(0), key(1), key(2), key(3), key(4)
].to_vec())
}
#[test]
fn creation() {
create_test_tunnel();
}
#[test]
fn test_next() {
let tunnel = create_test_tunnel();
assert_eq!(tunnel.next(&key(1), &key(3)), Some(key(2)));
assert_eq!(tunnel.next(&key(2), &key(0)), Some(key(1)));
assert_eq!(tunnel.next(&key(2), &key(2)), None);
}
#[test]
fn is_in_tunnel() {
let tunnel = create_test_tunnel();
assert!(tunnel.is_in_tunnel(&key(0)));
assert!(tunnel.is_in_tunnel(&key(1)));
assert!(tunnel.is_in_tunnel(&key(4)));
assert!(!tunnel.is_in_tunnel(&key(5)));
}
#[test]
fn tunnel_to() {
let tunnel = create_test_tunnel();
let me = &key(2);
assert_eq!(tunnel.tunnel_to(me, &key(5)), None);
assert_eq!(tunnel.tunnel_to(me, &key(3)), Some(
Tunnel::from_vec([key(2), key(3)].to_vec())
));
assert_eq!(tunnel.tunnel_to(me, &key(0)), Some(
Tunnel::from_vec([key(0), key(1), key(2)].to_vec())
));
}
}
}

117
src/message.rs

@ -1,48 +1,111 @@
use crate::crypto::{PublicKey, KeyPack};
use crate::crypto::{PublicKey, Keys, verify_sign};
use sha2::Digest;
use serde::{Serialize, Deserialize};
use postcard::{to_vec, from_bytes};
use heapless::{Vec, consts::*};
use alloc::vec::Vec;
use pinecone::{from_bytes, to_vec};
use crate::tunnel::Tunnel;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
fn get_hash(b: &Vec<u8>) -> Vec<u8> {
let mut hasher = sha2::Sha256::new();
hasher.input(b);
hasher.result().to_vec()
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub enum MsgType {
MultiCast,
ToTarget(PublicKey),
// No source, sign and tunnel
UniCast(PublicKey /* destination */),
// has source, sign and tunnel
Service, // Has source and sign but no tunnel
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Message {
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub enum Sign {
NoSign,
Signed(PublicKey /* source */, Vec<u8> /* sign */),
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub enum MsgTunnel {
NoTunnel,
Tunnel(Tunnel),
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct MessageContent {
/// MessageContent is part of the message that is signed
pub msg_type: MsgType,
pub body: Vec<u8, U11>,
pub source: PublicKey,
hash: u64,
sign: u64,
pub body: Vec<u8>,
}
impl MessageContent {
pub fn new(msg_type: MsgType, body: Vec<u8>) -> Self {
Self { msg_type, body }
}
pub fn get_hash(&self) -> Vec<u8> {
get_hash(&self.ser())
}
pub fn ser(&self) -> Vec<u8> {
to_vec(&self).expect("Message content serialization failed")
}
pub fn deserialize(serialized: Vec<u8>) -> Self {
from_bytes(&serialized).expect("Message content deserialization failed")
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Message {
pub content: MessageContent,
pub content_hash: Vec<u8>,
// hash for signing
pub hash: Vec<u8>,
// hash for checking integrity
pub sign: Sign,
pub tunnel: MsgTunnel,
}
impl Message {
fn get_hash(self) -> alloc::vec::Vec<u8> {
let mut hasher = sha2::Sha256::new();
hasher.input(self.ser());
hasher.result().to_vec()
pub fn get_hash(&self) -> Vec<u8> {
let mut msg2 = self.clone();
msg2.hash = Vec::<u8>::new();
get_hash(&msg2.ser())
}
pub fn new(msg_type: MsgType, body: Vec<u8, U11>, key_pack: KeyPack) -> Message {
let msg = Message { msg_type, body, source: key_pack.public_key, hash: 0, sign: 0 };
pub fn new(msg_type: MsgType, body: Vec<u8>, key_pack: &Keys) -> Message {
let content = MessageContent::new(msg_type.clone(), body);
let content_hash = content.get_hash();
let mut msg = Message {
content,
content_hash,
hash: Vec::<u8>::new(),
sign: Sign::NoSign,
tunnel: MsgTunnel::NoTunnel,
};
msg.sign = match msg_type {
MsgType::UniCast(_) | MsgType::Service => {
Sign::Signed(key_pack.get_public(), key_pack.sign(&msg.content_hash))
}
MsgType::MultiCast => { Sign::NoSign }
};
msg.hash = msg.get_hash();
msg
}
pub fn ser(self) -> Vec<u8, U11> {
to_vec(&self).unwrap()
pub fn verify(&self) -> bool {
self.hash == self.get_hash() && verify_sign(&self)
}
pub fn ser(&self) -> Vec<u8> {
to_vec(&self).expect("Message serialization failed")
}
pub fn deserialize(serialized: Vec<u8, U11>) -> Self {
Self{
msg_type: MsgType::MultiCast,
body: Vec::<u8, U11>::new(),
source: PublicKey { id: 0 },
hash: 0,
sign: 0
}
pub fn deserialize(serialized: Vec<u8>) -> Self {
from_bytes(&serialized).expect("Message deserialization failed")
}
}

101
src/transport.rs

@ -1,2 +1,101 @@
use crate::message::Message;
#[cfg(not(feature = "std"))]
use crate::message::MsgType;
use crate::crypto::PublicKey;
#[cfg(feature = "std")]
use crate::way::Way;
#[cfg(feature = "std")]
use crate::ways::get_all_possible_ways;
pub(crate) struct Transport {}
#[cfg(feature = "std")]
use std::thread;
#[cfg(feature = "std")]
use std::sync::{Arc, Mutex};
use alloc::vec::Vec;
#[cfg(feature = "std")]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
pub struct Transport {}
#[cfg(feature = "std")]
pub struct Transport {
pub ways: Vec<Box<dyn Way + Send + Sync>>,
pub msg_pool: Vec<(Message, PublicKey)>,
}
#[cfg(not(feature = "std"))]
impl Transport {
pub fn new() -> Self {
Self {}
}
pub fn send(&self, msg: &Message) {
// todo
}
pub fn receive(&self) -> (Message, PublicKey) {
(Message::new(MsgType::Service,
Vec::<u8>::new(),
&crate::crypto::Keys::gen()), PublicKey { key: [0u8; 32] })
}
pub fn send_service(&self, msg: &Message) {
// todo
// send message through radio (using pins)
}
pub fn send_to(&self, msg: &Message, to: &PublicKey) {
// todo
// send message through radio (using pins)
}
}
#[cfg(feature = "std")]
impl Transport {
pub fn new() -> Self {
let transport = Self { ways: get_all_possible_ways(), msg_pool: Vec::<(Message, PublicKey)>::new() };
transport
}
pub fn send_service(&self, msg: &Message) {
for way in &self.ways { // todo: do it in threads
way.send(&msg);
}
}
pub fn send_to(&self, msg: &Message, to: &PublicKey) {
for way in &self.ways {
way.send_to(&msg, to);
}
}
pub fn receive(&mut self) -> (Message, PublicKey) {
if self.msg_pool.len() != 0 {
let msg = self.msg_pool[0].clone();
self.msg_pool = self.msg_pool[1..].to_vec();
return msg;
}
return self.receive(); // recursion: infinite loop until we get a message (see exit condition above)
}
fn way_receiving_loop(&mut self, i: i32) {
let way = &self.ways[i as usize];
loop {
let (msg, key) = way.receive();
self.msg_pool.push((msg, key));
}
}
fn start_receiving_thread(&'static mut self) {
let way_num = self.ways.len();
let transport = Arc::new(Mutex::new(self));
for way in 0..way_num {
let current = transport.clone();
thread::spawn(move || {
current.lock().unwrap().way_receiving_loop(way as i32);
});
}
}
}

87
src/tunnel.rs

@ -0,0 +1,87 @@
use crate::crypto::PublicKey;
use alloc::vec::Vec;
use serde::{Serialize, Deserialize};
use core::option::Option;
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Tunnel {
nodes: Vec<PublicKey>
}
impl Tunnel {
pub fn from_vec(nodes: Vec<PublicKey>) -> Self {
Self { nodes }
}
pub fn is_in_tunnel(&self, node: &PublicKey) -> bool {
self.nodes
.iter()
.enumerate()
.find(|&current_node| current_node.1 == node).is_some()
}
pub fn tunnel_to(&self, me: &PublicKey, to: &PublicKey) -> Option<Tunnel> {
let my_index = self.nodes
.iter()
.enumerate()
.find(|&node| node.1 == me).unwrap().0;
match self.nodes
.iter()
.enumerate()
.find(|&node| node.1 == to) {
Some(en) => {
match my_index < en.0 {
true => { Some(Tunnel::from_vec(Vec::<PublicKey>::from(self.nodes.clone()[my_index..=en.0].to_vec()))) }
false => { Some(Tunnel::from_vec(Vec::<PublicKey>::from(self.nodes.clone()[en.0..=my_index].to_vec()))) }
}
}
None => {
None
}
}
}
fn index(&self, node: &PublicKey) -> Option<usize> {
match self.nodes
.iter()
.enumerate()
.find(|&current_node| current_node.1 == node) {
Some((index, _)) => Some(index),
None => None
}
}
pub fn get_next(&self, me: &PublicKey, forward: bool) -> Option<PublicKey> {
let my_index = self.index(me).unwrap();
if forward {
if my_index + 1 < self.nodes.len() {
Some(self.nodes[my_index + 1].clone())
} else {None}
} else {
if my_index > 0 {
Some(self.nodes[my_index - 1].clone())
} else { None }
}
}
pub fn next(&self, me: &PublicKey, to: &PublicKey) -> Option<PublicKey> {
let my_index = self.index(me);
let to_index = self.index(to);
if to_index == my_index {
return None;
}
self.get_next(me, to_index > my_index)
}
pub fn next_nodes(&self, me: &PublicKey) -> Vec<PublicKey> {
let my_index = self.nodes
.iter()
.enumerate()
.find(|&node| node.1 == me).unwrap().0;
let mut result = Vec::<PublicKey>::new();
if my_index > 0 { result.push(self.nodes[my_index - 1].clone()) };
if my_index < self.nodes.len() - 1 { result.push(self.nodes[my_index + 1].clone()) };
result
}
}

8
src/way.rs

@ -0,0 +1,8 @@
use crate::message::Message;
use crate::crypto::PublicKey;
pub trait Way {
fn send(&self, msg: &Message);
fn send_to(&self, msg: &Message, to: &PublicKey);
fn receive(&self) -> (Message, PublicKey);
}

8
src/ways/mod.rs

@ -0,0 +1,8 @@
use alloc::vec::Vec;
use alloc::boxed::Box;
use crate::way::Way;
pub fn get_all_possible_ways() -> Vec<Box<dyn Way + Send + Sync>> {
Vec::<Box<dyn Way + Send + Sync>>::new()
}
Loading…
Cancel
Save