feat(sim): world, contact trace, SimTransport
This commit is contained in:
Generated
+461
-2
@@ -2,6 +2,37 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-set"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56d87354e4229f54a44f7bf2435906a4656dba36026ab6eaca629a2c436a691c"
|
||||||
|
dependencies = [
|
||||||
|
"bit-vec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-vec"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5727b15fa97d4f4fee0a3b7c3d550ed0269f54329207b86388de918604e31269"
|
||||||
|
dependencies = [
|
||||||
|
"borsh",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake2"
|
name = "blake2"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@@ -20,12 +51,65 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "borsh"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a"
|
||||||
|
dependencies = [
|
||||||
|
"borsh-derive",
|
||||||
|
"bytes",
|
||||||
|
"cfg_aliases",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "borsh-derive"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12cdfe656708a01f89b451a7d36466e6fe6c414de0aa18fc54f864f6f9ca9f56"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cobs"
|
name = "cobs"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -35,6 +119,21 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core_detect"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@@ -56,6 +155,34 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
@@ -66,6 +193,29 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hash32"
|
name = "hash32"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -75,6 +225,12 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heapless"
|
name = "heapless"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -86,6 +242,49 @@ dependencies = [
|
|||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.191"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "postcard"
|
name = "postcard"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
@@ -96,6 +295,24 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-crate"
|
||||||
|
version = "3.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
|
||||||
|
dependencies = [
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.107"
|
version = "1.0.107"
|
||||||
@@ -105,6 +322,32 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proptest"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8530004ccb15eae51c7e40009fbe317f341f804db54dc033eec1c50be28cfa0"
|
||||||
|
dependencies = [
|
||||||
|
"bit-set",
|
||||||
|
"bit-vec",
|
||||||
|
"bitflags",
|
||||||
|
"chacha20",
|
||||||
|
"core_detect",
|
||||||
|
"num-traits",
|
||||||
|
"rand 0.10.3",
|
||||||
|
"rand_xorshift",
|
||||||
|
"regex-syntax",
|
||||||
|
"rusty-fork",
|
||||||
|
"tempfile",
|
||||||
|
"unarray",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.47"
|
version = "1.0.47"
|
||||||
@@ -114,6 +357,98 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xorshift"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60aa6af80be32871323012e02e6e65f8a7cc7890931ae421d217ad8fe0df2ccf"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusty-fork"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"quick-error",
|
||||||
|
"tempfile",
|
||||||
|
"wait-timeout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.229"
|
version = "1.0.229"
|
||||||
@@ -141,7 +476,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 3.0.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -156,6 +491,17 @@ version = "2.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.119"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "3.0.9"
|
version = "3.0.9"
|
||||||
@@ -167,6 +513,19 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.27.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.21"
|
version = "2.0.21"
|
||||||
@@ -184,7 +543,7 @@ checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 3.0.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -200,6 +559,41 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tines-sim"
|
name = "tines-sim"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proptest",
|
||||||
|
"rand 0.8.8",
|
||||||
|
"tines-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "1.1.2+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.25.17+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_parser",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.1.5+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
@@ -207,6 +601,12 @@ version = "1.20.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unarray"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
@@ -218,3 +618,62 @@ name = "version_check"
|
|||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wait-timeout"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.8.63"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.8.63"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|||||||
@@ -2,3 +2,10 @@
|
|||||||
name = "tines-sim"
|
name = "tines-sim"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tines-core = { path = "../tines-core" }
|
||||||
|
rand = "0.8"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
proptest = "1"
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//! tines-sim: a std simulator for the tines shared-memory library.
|
||||||
|
//!
|
||||||
|
//! `SimWorld` is a shared, reference-counted simulation of nodes connected by a
|
||||||
|
//! `ContactTrace`. `SimTransport` implements the `tines_core::Transport` trait
|
||||||
|
//! on top of that world: outbound frames are enqueued into per-node inboxes,
|
||||||
|
//! and `SimWorld::advance` turns contact-state changes into `Contact`/`Lost`
|
||||||
|
//! events. Loss and duplication are driven by a deterministic, seeded RNG so
|
||||||
|
//! that convergence behaviour is reproducible.
|
||||||
|
|
||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
pub mod trace;
|
||||||
|
pub mod world;
|
||||||
|
pub mod transport;
|
||||||
|
|
||||||
|
pub use trace::{Contact, ContactTrace};
|
||||||
|
pub use transport::SimTransport;
|
||||||
|
pub use world::{SimWorld, WorldConfig};
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
//! Contact traces: a timeline of which nodes are within range of each other.
|
||||||
|
|
||||||
|
/// A single contact window between two nodes.
|
||||||
|
///
|
||||||
|
/// Nodes `a` and `b` are in contact during the half-open interval
|
||||||
|
/// `[start_ms, end_ms)`. Contacts are symmetric: a contact recorded as
|
||||||
|
/// `(a, b)` is equivalent to `(b, a)`.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Contact {
|
||||||
|
pub start_ms: u64,
|
||||||
|
pub end_ms: u64,
|
||||||
|
pub a: usize,
|
||||||
|
pub b: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An ordered list of contact windows, as produced by the contact simulator.
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct ContactTrace {
|
||||||
|
pub contacts: Vec<Contact>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContactTrace {
|
||||||
|
/// Whether `a` and `b` are in contact at time `t`, for any contact
|
||||||
|
/// involving the pair in either order.
|
||||||
|
///
|
||||||
|
/// A contact counts during its half-open window: `start_ms <= t < end_ms`.
|
||||||
|
pub fn in_contact(&self, a: usize, b: usize, t: u64) -> bool {
|
||||||
|
self.contacts
|
||||||
|
.iter()
|
||||||
|
.any(|c| is_contact_pair(c, a, b) && in_window(c, t))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The last time any contact ends, or `0` if there are no contacts.
|
||||||
|
pub fn end(&self) -> u64 {
|
||||||
|
self.contacts.iter().map(|c| c.end_ms).max().unwrap_or(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True when `c` links `a` and `b` in either order.
|
||||||
|
fn is_contact_pair(c: &Contact, a: usize, b: usize) -> bool {
|
||||||
|
(c.a == a && c.b == b) || (c.a == b && c.b == a)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True when `t` falls inside the half-open window `[start, end)`.
|
||||||
|
fn in_window(c: &Contact, t: u64) -> bool {
|
||||||
|
c.start_ms <= t && t < c.end_ms
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{Contact, ContactTrace};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn in_contact_matches_both_orders() {
|
||||||
|
let mut trace = ContactTrace::default();
|
||||||
|
trace.contacts.push(Contact { start_ms: 100, end_ms: 200, a: 3, b: 7 });
|
||||||
|
assert!(!trace.in_contact(3, 7, 50)); // before the window
|
||||||
|
assert!(trace.in_contact(3, 7, 100)); // at the start edge
|
||||||
|
assert!(trace.in_contact(7, 3, 150)); // mid-window, either order
|
||||||
|
assert!(!trace.in_contact(3, 7, 200)); // at the end edge (half-open)
|
||||||
|
assert!(!trace.in_contact(3, 7, 300)); // after the window
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn end_is_zero_when_empty() {
|
||||||
|
assert_eq!(ContactTrace::default().end(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
//! SimTransport: a `Transport` implementation over a shared `SimWorld`.
|
||||||
|
//!
|
||||||
|
//! `SimTransport` is a datagram pipe bound to one node (`me`). Outbound frames
|
||||||
|
//! are checked against the live contact graph and the world's MTU, then
|
||||||
|
//! subjected to a loss roll and — on success — a duplication roll. All of this
|
||||||
|
//! mutates the shared `SimWorld`'s per-node mailboxes and frame counters, so
|
||||||
|
//! every participant shares one view of the network.
|
||||||
|
|
||||||
|
use crate::world::SimWorld;
|
||||||
|
use rand::Rng;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use tines_core::transport::{Event, FrameBuf, SendError, Transport};
|
||||||
|
|
||||||
|
/// A node's view of a shared `SimWorld`.
|
||||||
|
pub struct SimTransport {
|
||||||
|
world: Rc<RefCell<SimWorld>>,
|
||||||
|
me: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SimTransport {
|
||||||
|
/// Bind transport `me` to the shared `world`.
|
||||||
|
pub fn new(world: Rc<RefCell<SimWorld>>, me: usize) -> Self {
|
||||||
|
SimTransport { world, me }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transport for SimTransport {
|
||||||
|
type Addr = usize;
|
||||||
|
|
||||||
|
/// Pop the next queued event for this node, if any.
|
||||||
|
fn poll(&mut self) -> Option<Event<Self::Addr>> {
|
||||||
|
self.world.borrow_mut().inboxes[self.me].pop_front()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempt to deliver `frame` to `to`.
|
||||||
|
///
|
||||||
|
/// Order of checks: reachability, then MTU, then the loss roll. A frame that
|
||||||
|
/// survives loss is enqueued; a surviving frame is duplicated with the dup
|
||||||
|
/// roll (counting each enqueue toward `frames_sent`).
|
||||||
|
fn send(&mut self, to: &Self::Addr, frame: &[u8]) -> Result<(), SendError> {
|
||||||
|
let mut w = self.world.borrow_mut();
|
||||||
|
if !w.trace.in_contact(self.me, *to, w.prev_t) {
|
||||||
|
return Err(SendError::Unreachable);
|
||||||
|
}
|
||||||
|
if frame.len() > w.cfg.mtu {
|
||||||
|
return Err(SendError::TooLarge);
|
||||||
|
}
|
||||||
|
if w.rng.gen::<f64>() < w.cfg.loss {
|
||||||
|
w.frames_dropped += 1;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let buf = FrameBuf::from_slice(frame).map_err(|_| SendError::TooLarge)?;
|
||||||
|
w.inboxes[*to].push_back(Event::Frame(self.me, buf.clone()));
|
||||||
|
w.frames_sent += 1;
|
||||||
|
if w.rng.gen::<f64>() < w.cfg.dup {
|
||||||
|
w.inboxes[*to].push_back(Event::Frame(self.me, buf.clone()));
|
||||||
|
w.frames_sent += 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maximum frame size in bytes this transport can send.
|
||||||
|
fn mtu(&self) -> usize {
|
||||||
|
self.world.borrow().cfg.mtu
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
//! World configuration and the shared `SimWorld`.
|
||||||
|
//!
|
||||||
|
//! `SimWorld` is the heart of the simulator: it owns the contact trace, a
|
||||||
|
//! per-node inbound mailbox, the last-advanced time, and a seeded RNG that
|
||||||
|
//! governs loss and duplication. It is always held behind `Rc<RefCell<..>>` so
|
||||||
|
//! that many `SimTransport`s can share a single world.
|
||||||
|
|
||||||
|
use crate::trace::ContactTrace;
|
||||||
|
use rand::{rngs::StdRng, SeedableRng};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use tines_core::transport::Event;
|
||||||
|
|
||||||
|
/// World configuration for a `SimWorld`.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct WorldConfig {
|
||||||
|
pub nodes: usize,
|
||||||
|
pub mtu: usize,
|
||||||
|
pub loss: f64,
|
||||||
|
pub dup: f64,
|
||||||
|
pub seed: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A shared simulation of `nodes` connected by a `ContactTrace`.
|
||||||
|
///
|
||||||
|
/// Every node owns an inbound mailbox of `Event`s. `advance` walks every
|
||||||
|
/// unordered pair, emitting `Contact`/`Lost` where the contact graph changed
|
||||||
|
/// since the last advance. `SimTransport` uses the same mailboxes and the same
|
||||||
|
/// RNG (held here) to deliver and drop frames.
|
||||||
|
pub struct SimWorld {
|
||||||
|
pub(crate) cfg: WorldConfig,
|
||||||
|
pub(crate) trace: ContactTrace,
|
||||||
|
pub(crate) inboxes: Vec<VecDeque<Event<usize>>>,
|
||||||
|
pub(crate) prev_t: u64,
|
||||||
|
pub(crate) rng: StdRng,
|
||||||
|
pub(crate) frames_sent: u64,
|
||||||
|
pub(crate) frames_dropped: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SimWorld {
|
||||||
|
/// Build a world with empty mailboxes, `prev_t = 0`, and a seeded RNG.
|
||||||
|
pub fn new(cfg: WorldConfig, trace: ContactTrace) -> Rc<RefCell<SimWorld>> {
|
||||||
|
let seed = cfg.seed;
|
||||||
|
let inboxes = vec![VecDeque::new(); cfg.nodes];
|
||||||
|
let world = SimWorld {
|
||||||
|
cfg,
|
||||||
|
trace,
|
||||||
|
inboxes,
|
||||||
|
prev_t: 0,
|
||||||
|
rng: StdRng::seed_from_u64(seed),
|
||||||
|
frames_sent: 0,
|
||||||
|
frames_dropped: 0,
|
||||||
|
};
|
||||||
|
Rc::new(RefCell::new(world))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Advance the world to time `t`, emitting `Contact`/`Lost` for every pair
|
||||||
|
/// whose contact state changed since the previous advance.
|
||||||
|
pub fn advance(&mut self, t: u64) {
|
||||||
|
for a in 0..self.cfg.nodes {
|
||||||
|
for b in (a + 1)..self.cfg.nodes {
|
||||||
|
let old = self.trace.in_contact(a, b, self.prev_t);
|
||||||
|
let new = self.trace.in_contact(a, b, t);
|
||||||
|
if !old && new {
|
||||||
|
self.inboxes[a].push_back(Event::Contact(b));
|
||||||
|
self.inboxes[b].push_back(Event::Contact(a));
|
||||||
|
} else if old && !new {
|
||||||
|
self.inboxes[a].push_back(Event::Lost(b));
|
||||||
|
self.inboxes[b].push_back(Event::Lost(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.prev_t = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Total frames successfully enqueued (duplication counts each enqueue).
|
||||||
|
pub fn frames_sent(&self) -> u64 {
|
||||||
|
self.frames_sent
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Total frames dropped by the loss roll-out.
|
||||||
|
pub fn frames_dropped(&self) -> u64 {
|
||||||
|
self.frames_dropped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{SimWorld, WorldConfig};
|
||||||
|
use crate::trace::{Contact, ContactTrace};
|
||||||
|
use crate::transport::SimTransport;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use tines_core::transport::{Event, SendError, Transport};
|
||||||
|
|
||||||
|
/// A 2-node world where nodes 0 and 1 are in contact during
|
||||||
|
/// `[start, end)`, with the given loss/dup/mtu/seed.
|
||||||
|
fn two_node_world(
|
||||||
|
mtu: usize,
|
||||||
|
loss: f64,
|
||||||
|
dup: f64,
|
||||||
|
seed: u64,
|
||||||
|
start: u64,
|
||||||
|
end: u64,
|
||||||
|
) -> Rc<RefCell<SimWorld>> {
|
||||||
|
let cfg = WorldConfig {
|
||||||
|
nodes: 2,
|
||||||
|
mtu,
|
||||||
|
loss,
|
||||||
|
dup,
|
||||||
|
seed,
|
||||||
|
};
|
||||||
|
let mut trace = ContactTrace::default();
|
||||||
|
trace
|
||||||
|
.contacts
|
||||||
|
.push(Contact { start_ms: start, end_ms: end, a: 0, b: 1 });
|
||||||
|
SimWorld::new(cfg, trace)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A snapshot of everything currently queued in `node`'s inbox.
|
||||||
|
fn inbox(world: &Rc<RefCell<SimWorld>>, node: usize) -> Vec<Event<usize>> {
|
||||||
|
world.borrow().inboxes[node].iter().cloned().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The number of `Frame` events queued in `node`'s inbox.
|
||||||
|
fn frame_count(world: &Rc<RefCell<SimWorld>>, node: usize) -> usize {
|
||||||
|
world
|
||||||
|
.borrow()
|
||||||
|
.inboxes[node]
|
||||||
|
.iter()
|
||||||
|
.filter(|e| matches!(e, Event::Frame(_, _)))
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn advance_emits_contact_and_lost_at_window_edges() {
|
||||||
|
let world = two_node_world(1500, 0.0, 0.0, 42, 100, 200);
|
||||||
|
|
||||||
|
// Before the window opens, neither mailbox has anything.
|
||||||
|
world.borrow_mut().advance(50);
|
||||||
|
assert_eq!(inbox(&world, 0), Vec::<Event<usize>>::new());
|
||||||
|
assert_eq!(inbox(&world, 1), Vec::<Event<usize>>::new());
|
||||||
|
|
||||||
|
// At the start edge both peers learn of the contact.
|
||||||
|
world.borrow_mut().advance(100);
|
||||||
|
assert_eq!(inbox(&world, 0), vec![Event::Contact(1)]);
|
||||||
|
assert_eq!(inbox(&world, 1), vec![Event::Contact(0)]);
|
||||||
|
|
||||||
|
// At the end edge both peers learn of the loss.
|
||||||
|
world.borrow_mut().advance(200);
|
||||||
|
assert_eq!(inbox(&world, 0), vec![Event::Contact(1), Event::Lost(1)]);
|
||||||
|
assert_eq!(inbox(&world, 1), vec![Event::Contact(0), Event::Lost(0)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn send_outside_contact_is_unreachable() {
|
||||||
|
let cfg = WorldConfig {
|
||||||
|
nodes: 2,
|
||||||
|
mtu: 1500,
|
||||||
|
loss: 0.0,
|
||||||
|
dup: 0.0,
|
||||||
|
seed: 42,
|
||||||
|
};
|
||||||
|
let world = SimWorld::new(cfg, ContactTrace::default());
|
||||||
|
let mut t0 = SimTransport::new(world.clone(), 0);
|
||||||
|
assert_eq!(t0.send(&1, &[1, 2, 3]), Err(SendError::Unreachable));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn send_over_mtu_is_too_large() {
|
||||||
|
let world = two_node_world(8, 0.0, 0.0, 42, 0, 1000);
|
||||||
|
let mut t0 = SimTransport::new(world.clone(), 0);
|
||||||
|
assert_eq!(t0.send(&1, &[0u8; 9]), Err(SendError::TooLarge));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn loss_1_drops_everything() {
|
||||||
|
let world = two_node_world(1500, 1.0, 0.0, 42, 0, 1000);
|
||||||
|
let mut t0 = SimTransport::new(world.clone(), 0);
|
||||||
|
for _ in 0..100 {
|
||||||
|
t0.send(&1, &[1, 2, 3]).unwrap();
|
||||||
|
}
|
||||||
|
assert_eq!(frame_count(&world, 1), 0);
|
||||||
|
assert_eq!(world.borrow().frames_dropped(), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dup_1_doubles_everything() {
|
||||||
|
let world = two_node_world(1500, 0.0, 1.0, 42, 0, 1000);
|
||||||
|
let mut t0 = SimTransport::new(world.clone(), 0);
|
||||||
|
for _ in 0..10 {
|
||||||
|
t0.send(&1, &[1, 2, 3]).unwrap();
|
||||||
|
}
|
||||||
|
assert_eq!(frame_count(&world, 1), 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn same_seed_same_drops() {
|
||||||
|
let cfg = WorldConfig {
|
||||||
|
nodes: 2,
|
||||||
|
mtu: 1500,
|
||||||
|
loss: 0.5,
|
||||||
|
dup: 0.0,
|
||||||
|
seed: 1234,
|
||||||
|
};
|
||||||
|
let make_trace = || {
|
||||||
|
let mut trace = ContactTrace::default();
|
||||||
|
trace
|
||||||
|
.contacts
|
||||||
|
.push(Contact { start_ms: 0, end_ms: 1000, a: 0, b: 1 });
|
||||||
|
trace
|
||||||
|
};
|
||||||
|
let w1 = SimWorld::new(cfg.clone(), make_trace());
|
||||||
|
let w2 = SimWorld::new(cfg.clone(), make_trace());
|
||||||
|
let mut t1 = SimTransport::new(w1.clone(), 0);
|
||||||
|
let mut t2 = SimTransport::new(w2.clone(), 0);
|
||||||
|
for _ in 0..50 {
|
||||||
|
t1.send(&1, &[1]).unwrap();
|
||||||
|
t2.send(&1, &[1]).unwrap();
|
||||||
|
}
|
||||||
|
assert_eq!(w1.borrow().frames_dropped(), w2.borrow().frames_dropped());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user