mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-10-01 01:26:08 -04:00
Merge branch 'main' into add-contributor-docs
This commit is contained in:
commit
035a650159
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.1.4
|
||||
current_version = 0.1.7
|
||||
|
||||
[bumpversion:file:veilid-server/Cargo.toml]
|
||||
search = name = "veilid-server"
|
||||
|
106
.gitlab-ci.yml
106
.gitlab-ci.yml
@ -7,75 +7,153 @@ variables:
|
||||
stages:
|
||||
- test
|
||||
- build_packages
|
||||
- release
|
||||
- distribute
|
||||
|
||||
#before_script:
|
||||
# - earthly bootstrap
|
||||
|
||||
create_test_machine:
|
||||
stage: test
|
||||
only:
|
||||
- main
|
||||
- merge_requests
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh create amd64-deb
|
||||
when: manual
|
||||
|
||||
test_amd64:
|
||||
stage: test
|
||||
image: earthly/earthly:v0.6.30
|
||||
only:
|
||||
- main
|
||||
- merge_requests
|
||||
needs:
|
||||
- create_test_machine
|
||||
tags:
|
||||
- build-server
|
||||
- earthly-tests
|
||||
script:
|
||||
- earthly bootstrap
|
||||
- earthly --ci +unit-tests-linux-amd64
|
||||
when: manual
|
||||
|
||||
delete_test_machine:
|
||||
stage: test
|
||||
only:
|
||||
- main
|
||||
- merge_requests
|
||||
needs:
|
||||
- test_amd64
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh delete amd64-deb
|
||||
|
||||
release_job:
|
||||
stage: release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
script:
|
||||
- echo "running release_job"
|
||||
release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
|
||||
tag_name: '$CI_COMMIT_TAG'
|
||||
description: '$CI_COMMIT_TAG'
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
create_build_machines:
|
||||
stage: build_packages
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh create amd64-deb
|
||||
- /home/gitlab-runner/build-machine-ctl.sh create arm64-deb
|
||||
- /home/gitlab-runner/build-machine-ctl.sh create amd64-rpm
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
package_amd64_deb:
|
||||
stage: build_packages
|
||||
only:
|
||||
- stable
|
||||
needs:
|
||||
- create_build_machines
|
||||
tags:
|
||||
- build-amd64-deb
|
||||
script:
|
||||
- earthly bootstrap
|
||||
- earthly +package-linux-amd64-deb
|
||||
- /home/gitlab-runner/scp-to-orchestrator.sh
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
delete_amd64_deb_build_machine:
|
||||
stage: build_packages
|
||||
needs:
|
||||
- package_amd64_deb
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh delete amd64-deb
|
||||
|
||||
package_arm64_deb:
|
||||
stage: build_packages
|
||||
only:
|
||||
- stable
|
||||
needs:
|
||||
- create_build_machines
|
||||
tags:
|
||||
- build-arm64-deb
|
||||
script:
|
||||
- earthly bootstrap
|
||||
- earthly +package-linux-arm64-deb
|
||||
- /home/gitlab-runner/scp-to-orchestrator.sh
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
delete_arm64_deb_build_machine:
|
||||
stage: build_packages
|
||||
needs:
|
||||
- package_arm64_deb
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh delete arm64-deb
|
||||
|
||||
package_amd64_rpm:
|
||||
stage: build_packages
|
||||
only:
|
||||
- stable
|
||||
needs:
|
||||
- create_build_machines
|
||||
tags:
|
||||
- build-amd64-rpm
|
||||
script:
|
||||
- earthly bootstrap
|
||||
- earthly +package-linux-amd64-rpm
|
||||
- /home/gitlab-runner/scp-to-orchestrator.sh
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
delete_amd64_rpm_build_machine:
|
||||
stage: build_packages
|
||||
needs:
|
||||
- package_amd64_rpm
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/build-machine-ctl.sh delete amd64-rpm
|
||||
|
||||
build_repositories:
|
||||
stage: distribute
|
||||
only:
|
||||
- stable
|
||||
tags:
|
||||
- build-orchestration
|
||||
script:
|
||||
- /home/gitlab-runner/distribute-packages.sh
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
||||
|
||||
deploy_repos:
|
||||
stage: distribute
|
||||
only:
|
||||
- stable
|
||||
needs:
|
||||
- build_repositories
|
||||
tags:
|
||||
- repo-server
|
||||
script:
|
||||
- /home/gitlab-runner/deploy-repo.sh
|
||||
|
||||
#Note so merge works
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /v\d.+/'
|
18
CHANGELOG.md
Normal file
18
CHANGELOG.md
Normal file
@ -0,0 +1,18 @@
|
||||
**Changes in Veilid 0.1.7**
|
||||
|
||||
- Fix for connection table crash
|
||||
- Fix for incorrect set_dht_value return value
|
||||
- Python test updates
|
||||
- Various VeilidChat-prompted veilid-flutter updates
|
||||
|
||||
**Changes in Veilid 0.1.6**
|
||||
|
||||
- Fix for 'find_node' too many nodes returned issue
|
||||
|
||||
**Changes in Veilid 0.1.5**
|
||||
|
||||
- Added Changelog
|
||||
- Fix detachment issue with suspending network interfaces during operation
|
||||
- Fix incorrect punishment on relayed undecryptable messages
|
||||
- Minor API feature adds
|
||||
- Relay bugfixes
|
232
Cargo.lock
generated
232
Cargo.lock
generated
@ -252,7 +252,7 @@ dependencies = [
|
||||
"async-lock",
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"fastrand 1.9.0",
|
||||
"futures-lite",
|
||||
"slab",
|
||||
]
|
||||
@ -286,7 +286,7 @@ dependencies = [
|
||||
"log",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix",
|
||||
"rustix 0.37.23",
|
||||
"slab",
|
||||
"socket2 0.4.9",
|
||||
"waker-fn",
|
||||
@ -314,7 +314,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"rustix",
|
||||
"rustix 0.37.23",
|
||||
"signal-hook",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
@ -381,7 +381,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -419,13 +419,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.71"
|
||||
version = "0.1.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
|
||||
checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -457,9 +457,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async_executors"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0b2463773401e1f684136f9cdb956cf611f22172472cf3f049e72123f59e359"
|
||||
checksum = "a982d2f86de6137cc05c9db9a915a19886c97911f9790d04f174cede74be01a5"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"blanket",
|
||||
@ -694,13 +694,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "blanket"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b04ce3d2372d05d1ef4ea3fdf427da6ae3c17ca06d688a107b5344836276bc3"
|
||||
checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -753,7 +753,7 @@ dependencies = [
|
||||
"async-lock",
|
||||
"async-task",
|
||||
"atomic-waker",
|
||||
"fastrand",
|
||||
"fastrand 1.9.0",
|
||||
"futures-lite",
|
||||
"log",
|
||||
]
|
||||
@ -1294,7 +1294,7 @@ dependencies = [
|
||||
"flexi_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"time 0.3.23",
|
||||
"time 0.3.24",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
@ -1336,7 +1336,7 @@ dependencies = [
|
||||
"owning_ref",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"time 0.3.23",
|
||||
"time 0.3.24",
|
||||
"tokio",
|
||||
"toml 0.7.6",
|
||||
"unicode-segmentation",
|
||||
@ -1419,7 +1419,7 @@ dependencies = [
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1441,7 +1441,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core 0.20.3",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1463,6 +1463,12 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01"
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
@ -1556,9 +1562,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "enum-as-inner"
|
||||
@ -1589,7 +1595,7 @@ checksum = "8560b409800a72d2d7860f8e5f4e0b0bd22bea6a352ea2a9ce30ccdef7f16d2f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1632,7 +1638,7 @@ dependencies = [
|
||||
"darling 0.20.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1676,9 +1682,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
|
||||
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
@ -1764,6 +1770,12 @@ dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.0"
|
||||
@ -1814,7 +1826,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustversion",
|
||||
"thiserror",
|
||||
"time 0.3.23",
|
||||
"time 0.3.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1930,7 +1942,7 @@ version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"fastrand 1.9.0",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
@ -1947,7 +1959,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2752,9 +2764,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.9"
|
||||
version = "1.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
|
||||
checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -2774,6 +2786,12 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
@ -2840,9 +2858,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
|
||||
checksum = "67827e6ea8ee8a7c4a72227ef4fc08957040acffdb5f122733b24fa12daff41b"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@ -3224,9 +3242,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -3596,7 +3614,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3667,7 +3685,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3846,9 +3864,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -3979,7 +3997,7 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.3.3",
|
||||
"regex-automata 0.3.4",
|
||||
"regex-syntax 0.7.4",
|
||||
]
|
||||
|
||||
@ -3994,9 +4012,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
||||
checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -4165,7 +4183,20 @@ dependencies = [
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"linux-raw-sys 0.3.8",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5"
|
||||
dependencies = [
|
||||
"bitflags 2.3.3",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.3",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
@ -4212,16 +4243,6 @@ dependencies = [
|
||||
"base64 0.21.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
@ -4321,9 +4342,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.1"
|
||||
version = "2.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
|
||||
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation 0.9.3",
|
||||
@ -4334,9 +4355,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.9.0"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
|
||||
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.8.4",
|
||||
"libc",
|
||||
@ -4380,9 +4401,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.173"
|
||||
version = "1.0.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f"
|
||||
checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -4408,13 +4429,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.173"
|
||||
version = "1.0.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49"
|
||||
checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4430,9 +4451,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.103"
|
||||
version = "1.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b"
|
||||
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -4441,13 +4462,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.14"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731"
|
||||
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4461,9 +4482,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.24"
|
||||
version = "0.9.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd5f51e3fdb5b9cdd1577e1cb7a733474191b1aca6a72c2e50913241632c1180"
|
||||
checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"itoa",
|
||||
@ -4637,9 +4658,9 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.5"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
@ -4649,7 +4670,7 @@ checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369"
|
||||
dependencies = [
|
||||
"log",
|
||||
"termcolor",
|
||||
"time 0.3.23",
|
||||
"time 0.3.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4831,9 +4852,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.26"
|
||||
version = "2.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970"
|
||||
checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -4874,15 +4895,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
|
||||
checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"fastrand 2.0.0",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix",
|
||||
"rustix 0.38.4",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
@ -4912,22 +4932,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
|
||||
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
|
||||
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4979,16 +4999,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
|
||||
checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros 0.2.10",
|
||||
"time-macros 0.2.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5009,9 +5030,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.10"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
|
||||
checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd"
|
||||
dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
@ -5083,7 +5104,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5280,7 +5301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"time 0.3.23",
|
||||
"time 0.3.24",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@ -5292,7 +5313,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5627,7 +5648,7 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "veilid-cli"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"async-std",
|
||||
@ -5663,7 +5684,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veilid-core"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"async-io",
|
||||
@ -5755,7 +5776,7 @@ dependencies = [
|
||||
"weak-table",
|
||||
"web-sys",
|
||||
"webpki 0.22.0",
|
||||
"webpki-roots 0.24.0",
|
||||
"webpki-roots 0.25.1",
|
||||
"wee_alloc",
|
||||
"winapi",
|
||||
"windows 0.38.0",
|
||||
@ -5766,7 +5787,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veilid-flutter"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"allo-isolate",
|
||||
"async-std",
|
||||
@ -5795,7 +5816,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veilid-server"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"async-std",
|
||||
@ -5845,7 +5866,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veilid-tools"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"android-logd-logger",
|
||||
"async-lock",
|
||||
@ -5896,7 +5917,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veilid-wasm"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"console_error_panic_hook",
|
||||
@ -5996,7 +6017,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -6030,7 +6051,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -6132,12 +6153,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.24.0"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888"
|
||||
dependencies = [
|
||||
"rustls-webpki",
|
||||
]
|
||||
checksum = "c9c6eda1c830a36f361e7721c87fd79ea84293b54f8c48c959f85ec636f0f196"
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
@ -6438,9 +6456,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.0"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
|
||||
checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -6547,7 +6565,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"derivative",
|
||||
"enumflags2",
|
||||
"fastrand",
|
||||
"fastrand 1.9.0",
|
||||
"futures",
|
||||
"nb-connect",
|
||||
"nix 0.22.3",
|
||||
@ -6589,7 +6607,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -115,10 +115,12 @@ build-linux-arm64:
|
||||
# Unit tests
|
||||
unit-tests-linux-amd64:
|
||||
FROM +code-linux
|
||||
ENV RUST_BACKTRACE=1
|
||||
RUN cargo test --target x86_64-unknown-linux-gnu --release -p veilid-server -p veilid-cli -p veilid-tools -p veilid-core
|
||||
|
||||
# unit-tests-linux-arm64:
|
||||
# FROM +code-linux
|
||||
# ENV RUST_BACKTRACE=1
|
||||
# RUN cargo test --target aarch64-unknown-linux-gnu --release -p veilid-server -p veilid-cli -p veilid-tools -p veilid-core
|
||||
|
||||
# Package
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-cli"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-core"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
@ -330,7 +330,15 @@ impl Envelope {
|
||||
self.sender_id
|
||||
}
|
||||
|
||||
pub fn get_sender_typed_id(&self) -> TypedKey {
|
||||
TypedKey::new(self.crypto_kind, self.sender_id)
|
||||
}
|
||||
|
||||
pub fn get_recipient_id(&self) -> PublicKey {
|
||||
self.recipient_id
|
||||
}
|
||||
|
||||
pub fn get_recipient_typed_id(&self) -> TypedKey {
|
||||
TypedKey::new(self.crypto_kind, self.recipient_id)
|
||||
}
|
||||
}
|
||||
|
@ -207,6 +207,11 @@ impl Receipt {
|
||||
pub fn get_sender_id(&self) -> PublicKey {
|
||||
self.sender_id
|
||||
}
|
||||
|
||||
pub fn get_sender_typed_id(&self) -> TypedKey {
|
||||
TypedKey::new(self.crypto_kind, self.sender_id)
|
||||
}
|
||||
|
||||
pub fn get_extra_data(&self) -> &[u8] {
|
||||
&self.extra_data
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
use super::*;
|
||||
|
||||
use libc::{
|
||||
|
@ -344,9 +344,9 @@ impl NetworkInterfaces {
|
||||
let mut last_interfaces = {
|
||||
let mut last_interfaces = BTreeMap::<String, NetworkInterface>::new();
|
||||
let mut platform_support = PlatformSupport::new()?;
|
||||
platform_support
|
||||
.get_interfaces(&mut last_interfaces)
|
||||
.await?;
|
||||
if let Err(e) = platform_support.get_interfaces(&mut last_interfaces).await {
|
||||
debug!("no network interfaces are enabled: {}", e);
|
||||
}
|
||||
last_interfaces
|
||||
};
|
||||
|
||||
@ -395,10 +395,16 @@ impl NetworkInterfaces {
|
||||
continue;
|
||||
}
|
||||
if let Some(pipv4) = intf.primary_ipv4() {
|
||||
intf_addrs.push(pipv4);
|
||||
// Skip temporary addresses because they're going to change
|
||||
if !pipv4.is_temporary() {
|
||||
intf_addrs.push(pipv4);
|
||||
}
|
||||
}
|
||||
if let Some(pipv6) = intf.primary_ipv6() {
|
||||
intf_addrs.push(pipv6);
|
||||
// Skip temporary addresses because they're going to change
|
||||
if !pipv6.is_temporary() {
|
||||
intf_addrs.push(pipv6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,10 +177,10 @@ impl ConnectionTable {
|
||||
// then drop the least recently used connection
|
||||
let mut out_conn = None;
|
||||
if inner.conn_by_id[protocol_index].len() > inner.max_connections[protocol_index] {
|
||||
if let Some((lruk, lru_conn)) = inner.conn_by_id[protocol_index].remove_lru() {
|
||||
if let Some((lruk, lru_conn)) = inner.conn_by_id[protocol_index].peek_lru() {
|
||||
let lruk = *lruk;
|
||||
log_net!(debug "connection lru out: {:?}", lru_conn);
|
||||
out_conn = Some(lru_conn);
|
||||
Self::remove_connection_records(&mut *inner, lruk);
|
||||
out_conn = Some(Self::remove_connection_records(&mut *inner, lruk));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,6 +954,7 @@ impl NetworkManager {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(debug "envelope failed to decode: {}", e);
|
||||
// safe to punish here because relays also check here to ensure they arent forwarding things that don't decode
|
||||
self.address_filter().punish_ip_addr(remote_addr);
|
||||
return Ok(false);
|
||||
}
|
||||
@ -1005,12 +1006,12 @@ impl NetworkManager {
|
||||
|
||||
// Peek at header and see if we need to relay this
|
||||
// If the recipient id is not our node id, then it needs relaying
|
||||
let sender_id = TypedKey::new(envelope.get_crypto_kind(), envelope.get_sender_id());
|
||||
let sender_id = envelope.get_sender_typed_id();
|
||||
if self.address_filter().is_node_id_punished(sender_id) {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let recipient_id = TypedKey::new(envelope.get_crypto_kind(), envelope.get_recipient_id());
|
||||
let recipient_id = envelope.get_recipient_typed_id();
|
||||
if !routing_table.matches_own_node_id(&[recipient_id]) {
|
||||
// See if the source node is allowed to resolve nodes
|
||||
// This is a costly operation, so only outbound-relay permitted
|
||||
@ -1089,15 +1090,18 @@ impl NetworkManager {
|
||||
) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(debug "failed to decrypt envelope body: {}",e);
|
||||
self.address_filter().punish_ip_addr(remote_addr);
|
||||
log_net!(debug "failed to decrypt envelope body: {}", e);
|
||||
// Can't punish by ip address here because relaying can't decrypt envelope bodies to check
|
||||
// But because the envelope was properly signed by the time it gets here, it is safe to
|
||||
// punish by node id
|
||||
self.address_filter().punish_node_id(sender_id);
|
||||
return Ok(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Cache the envelope information in the routing table
|
||||
let source_noderef = match routing_table.register_node_with_existing_connection(
|
||||
TypedKey::new(envelope.get_crypto_kind(), envelope.get_sender_id()),
|
||||
envelope.get_sender_typed_id(),
|
||||
connection_descriptor,
|
||||
ts,
|
||||
) {
|
||||
|
@ -315,7 +315,7 @@ impl NetworkConnection {
|
||||
return RecvLoopAction::Finish;
|
||||
}
|
||||
|
||||
// Punish invalid messages
|
||||
// Punish invalid framing (tcp framing or websocket framing)
|
||||
if v.is_invalid_message() {
|
||||
address_filter.punish_ip_addr(peer_address.to_socket_addr().ip());
|
||||
return RecvLoopAction::Finish;
|
||||
|
@ -1054,8 +1054,8 @@ impl RoutingTableInner {
|
||||
nodes.sort_by(|a, b| compare(self, a, b));
|
||||
|
||||
// return transformed vector for filtered+sorted nodes
|
||||
let cnt = usize::min(node_count, nodes.len());
|
||||
let mut out = Vec::<O>::with_capacity(cnt);
|
||||
nodes.truncate(node_count);
|
||||
let mut out = Vec::<O>::with_capacity(nodes.len());
|
||||
for node in nodes {
|
||||
let val = transform(self, node);
|
||||
out.push(val);
|
||||
|
@ -81,7 +81,9 @@ pub struct RPCOperationFindNodeA {
|
||||
impl RPCOperationFindNodeA {
|
||||
pub fn new(peers: Vec<PeerInfo>) -> Result<Self, RPCError> {
|
||||
if peers.len() > MAX_FIND_NODE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("find node peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"encoded find node peers length too long",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self { peers })
|
||||
@ -106,7 +108,9 @@ impl RPCOperationFindNodeA {
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
|
||||
if peers_reader.len() as usize > MAX_FIND_NODE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("find node peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"decoded find node peers length too long",
|
||||
));
|
||||
}
|
||||
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
|
@ -89,7 +89,9 @@ impl RPCOperationGetValueA {
|
||||
descriptor: Option<SignedValueDescriptor>,
|
||||
) -> Result<Self, RPCError> {
|
||||
if peers.len() > MAX_GET_VALUE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("GetValueA peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"encoded GetValueA peers length too long",
|
||||
));
|
||||
}
|
||||
Ok(Self {
|
||||
value,
|
||||
@ -175,7 +177,9 @@ impl RPCOperationGetValueA {
|
||||
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
if peers_reader.len() as usize > MAX_GET_VALUE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("GetValueA peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"decoded GetValueA peers length too long",
|
||||
));
|
||||
}
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
|
@ -123,7 +123,9 @@ impl RPCOperationSetValueA {
|
||||
peers: Vec<PeerInfo>,
|
||||
) -> Result<Self, RPCError> {
|
||||
if peers.len() as usize > MAX_SET_VALUE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("SetValueA peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"encoded SetValueA peers length too long",
|
||||
));
|
||||
}
|
||||
Ok(Self { set, value, peers })
|
||||
}
|
||||
@ -182,7 +184,9 @@ impl RPCOperationSetValueA {
|
||||
};
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
if peers_reader.len() as usize > MAX_SET_VALUE_A_PEERS_LEN {
|
||||
return Err(RPCError::protocol("SetValueA peers length too long"));
|
||||
return Err(RPCError::protocol(
|
||||
"decoded SetValueA peers length too long",
|
||||
));
|
||||
}
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
|
@ -319,10 +319,7 @@ impl RPCProcessor {
|
||||
};
|
||||
|
||||
// Reply directly to the request's source
|
||||
let sender_node_id = TypedKey::new(
|
||||
detail.envelope.get_crypto_kind(),
|
||||
detail.envelope.get_sender_id(),
|
||||
);
|
||||
let sender_node_id = detail.envelope.get_sender_typed_id();
|
||||
|
||||
// This may be a different node's reference than the 'sender' in the case of a relay
|
||||
let peer_noderef = detail.peer_noderef.clone();
|
||||
|
@ -126,17 +126,9 @@ impl RPCMessageHeader {
|
||||
}
|
||||
pub fn direct_sender_node_id(&self) -> TypedKey {
|
||||
match &self.detail {
|
||||
RPCMessageHeaderDetail::Direct(d) => {
|
||||
TypedKey::new(d.envelope.get_crypto_kind(), d.envelope.get_sender_id())
|
||||
}
|
||||
RPCMessageHeaderDetail::SafetyRouted(s) => TypedKey::new(
|
||||
s.direct.envelope.get_crypto_kind(),
|
||||
s.direct.envelope.get_sender_id(),
|
||||
),
|
||||
RPCMessageHeaderDetail::PrivateRouted(p) => TypedKey::new(
|
||||
p.direct.envelope.get_crypto_kind(),
|
||||
p.direct.envelope.get_sender_id(),
|
||||
),
|
||||
RPCMessageHeaderDetail::Direct(d) => d.envelope.get_sender_typed_id(),
|
||||
RPCMessageHeaderDetail::SafetyRouted(s) => s.direct.envelope.get_sender_typed_id(),
|
||||
RPCMessageHeaderDetail::PrivateRouted(p) => p.direct.envelope.get_sender_typed_id(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1464,10 +1456,7 @@ impl RPCProcessor {
|
||||
let msg = match &encoded_msg.header.detail {
|
||||
RPCMessageHeaderDetail::Direct(detail) => {
|
||||
// Get sender node id
|
||||
let sender_node_id = TypedKey::new(
|
||||
detail.envelope.get_crypto_kind(),
|
||||
detail.envelope.get_sender_id(),
|
||||
);
|
||||
let sender_node_id = detail.envelope.get_sender_typed_id();
|
||||
|
||||
// Decode and validate the RPC operation
|
||||
let operation = match self.decode_rpc_operation(&encoded_msg) {
|
||||
@ -1689,7 +1678,10 @@ impl RPCProcessor {
|
||||
|
||||
let send_channel = {
|
||||
let inner = self.inner.lock();
|
||||
inner.send_channel.as_ref().unwrap().clone()
|
||||
let Some(send_channel) = inner.send_channel.as_ref().cloned() else {
|
||||
bail!("send channel is closed");
|
||||
};
|
||||
send_channel
|
||||
};
|
||||
let span_id = Span::current().id();
|
||||
send_channel
|
||||
@ -1725,7 +1717,10 @@ impl RPCProcessor {
|
||||
};
|
||||
let send_channel = {
|
||||
let inner = self.inner.lock();
|
||||
inner.send_channel.as_ref().unwrap().clone()
|
||||
let Some(send_channel) = inner.send_channel.as_ref().cloned() else {
|
||||
bail!("send channel is closed");
|
||||
};
|
||||
send_channel
|
||||
};
|
||||
let span_id = Span::current().id();
|
||||
send_channel
|
||||
@ -1764,7 +1759,10 @@ impl RPCProcessor {
|
||||
|
||||
let send_channel = {
|
||||
let inner = self.inner.lock();
|
||||
inner.send_channel.as_ref().unwrap().clone()
|
||||
let Some(send_channel) = inner.send_channel.as_ref().cloned() else {
|
||||
bail!("send channel is closed");
|
||||
};
|
||||
send_channel
|
||||
};
|
||||
let span_id = Span::current().id();
|
||||
send_channel
|
||||
|
@ -104,10 +104,7 @@ impl RPCProcessor {
|
||||
// We filter on the -outgoing- protocol capability status not the node's dial info
|
||||
// Use the address type though, to ensure we reach an ipv6 capable node if this is
|
||||
// an ipv6 address
|
||||
let sender_node_id = TypedKey::new(
|
||||
detail.envelope.get_crypto_kind(),
|
||||
detail.envelope.get_sender_id(),
|
||||
);
|
||||
let sender_node_id = detail.envelope.get_sender_typed_id();
|
||||
let routing_domain = detail.routing_domain;
|
||||
let node_count = {
|
||||
let c = self.config.get();
|
||||
|
@ -347,8 +347,9 @@ impl StorageManager {
|
||||
if last_signed_value_data.value_data().data() == &data
|
||||
&& last_signed_value_data.value_data().writer() == &writer.key
|
||||
{
|
||||
// Data and writer is the name, nothing is changing, just return the same ValueData
|
||||
return Ok(Some(last_signed_value_data.into_value_data()));
|
||||
// Data and writer is the same, nothing is changing,
|
||||
// just return that we set it, but no network activity needs to happen
|
||||
return Ok(None);
|
||||
}
|
||||
let seq = last_signed_value_data.value_data().seq();
|
||||
ValueData::new_with_seq(seq + 1, data, writer.key)
|
||||
@ -380,7 +381,7 @@ impl StorageManager {
|
||||
|
||||
// Add to offline writes to flush
|
||||
inner.offline_subkey_writes.entry(key).and_modify(|x| { x.insert(subkey); } ).or_insert(ValueSubkeyRangeSet::single(subkey));
|
||||
return Ok(Some(signed_value_data.into_value_data()))
|
||||
return Ok(None)
|
||||
};
|
||||
|
||||
// Drop the lock for network access
|
||||
@ -393,7 +394,7 @@ impl StorageManager {
|
||||
key,
|
||||
subkey,
|
||||
safety_selection,
|
||||
signed_value_data,
|
||||
signed_value_data.clone(),
|
||||
descriptor,
|
||||
)
|
||||
.await?;
|
||||
@ -404,7 +405,13 @@ impl StorageManager {
|
||||
.handle_set_local_value(key, subkey, final_signed_value_data.clone())
|
||||
.await?;
|
||||
|
||||
Ok(Some(final_signed_value_data.into_value_data()))
|
||||
// Return the new value if it differs from what was asked to set
|
||||
if final_signed_value_data.value_data() != signed_value_data.value_data() {
|
||||
return Ok(Some(final_signed_value_data.into_value_data()));
|
||||
}
|
||||
|
||||
// If the original value was set, return None
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub async fn watch_values(
|
||||
|
1
veilid-core/src/tests/files/flag.txt
Normal file
1
veilid-core/src/tests/files/flag.txt
Normal file
@ -0,0 +1 @@
|
||||
Ray says "Go SubSix!"
|
@ -96,7 +96,7 @@ impl DHTSchemaSMPL {
|
||||
impl TryFrom<&[u8]> for DHTSchemaSMPL {
|
||||
type Error = VeilidAPIError;
|
||||
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
|
||||
if b.len() != Self::FIXED_SIZE {
|
||||
if b.len() < Self::FIXED_SIZE {
|
||||
apibail_generic!("invalid size");
|
||||
}
|
||||
if &b[0..4] != &Self::FCC {
|
||||
|
@ -1,5 +1,11 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
include: package:lint_hard/all.yaml
|
||||
analyzer:
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
exclude:
|
||||
- '**/*.g.dart'
|
||||
- '**/*.freezed.dart'
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_positional_boolean_parameters: false
|
@ -3,3 +3,7 @@ include: package:flutter_lints/flutter.yaml
|
||||
analyzer:
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- unawaited_futures
|
@ -357,6 +357,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
system_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: system_info_plus
|
||||
sha256: b915c811c6605b802f3988859bc2bb79c95f735762a75b5451741f7a2b949d1b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.5"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -395,7 +403,7 @@ packages:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.1.1"
|
||||
version: "0.1.6"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1,7 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:system_info2/system_info2.dart' as sysinfo;
|
||||
import 'package:system_info_plus/system_info_plus.dart';
|
||||
|
||||
import 'veilid.dart';
|
||||
|
||||
const int megaByte = 1024 * 1024;
|
||||
@ -13,10 +17,13 @@ int getLocalSubkeyCacheSize() {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
int getLocalMaxSubkeyCacheMemoryMb() {
|
||||
Future<int> getLocalMaxSubkeyCacheMemoryMb() async {
|
||||
if (kIsWeb) {
|
||||
return 256;
|
||||
}
|
||||
if (Platform.isIOS || Platform.isAndroid) {
|
||||
return (await SystemInfoPlus.physicalMemory ?? 2048) ~/ 32;
|
||||
}
|
||||
return sysinfo.SysInfo.getTotalPhysicalMemory() ~/ 32 ~/ megaByte;
|
||||
}
|
||||
|
||||
@ -34,10 +41,13 @@ int getRemoteMaxRecords() {
|
||||
return 128;
|
||||
}
|
||||
|
||||
int getRemoteMaxSubkeyCacheMemoryMb() {
|
||||
Future<int> getRemoteMaxSubkeyCacheMemoryMb() async {
|
||||
if (kIsWeb) {
|
||||
return 256;
|
||||
}
|
||||
if (Platform.isIOS || Platform.isAndroid) {
|
||||
return (await SystemInfoPlus.physicalMemory ?? 2048) ~/ 32;
|
||||
}
|
||||
return sysinfo.SysInfo.getTotalPhysicalMemory() ~/ 32 ~/ megaByte;
|
||||
}
|
||||
|
||||
@ -48,136 +58,129 @@ int getRemoteMaxStorageSpaceMb() {
|
||||
return 256;
|
||||
}
|
||||
|
||||
Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
|
||||
return VeilidConfig(
|
||||
programName: programName,
|
||||
namespace: "",
|
||||
capabilities: const VeilidConfigCapabilities(disable: []),
|
||||
protectedStore: const VeilidConfigProtectedStore(
|
||||
allowInsecureFallback: false,
|
||||
alwaysUseInsecureStorage: false,
|
||||
directory: "",
|
||||
delete: false,
|
||||
deviceEncryptionKeyPassword: "",
|
||||
newDeviceEncryptionKeyPassword: null,
|
||||
),
|
||||
tableStore: VeilidConfigTableStore(
|
||||
directory: kIsWeb
|
||||
? ""
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
"table_store"),
|
||||
delete: false,
|
||||
),
|
||||
blockStore: VeilidConfigBlockStore(
|
||||
directory: kIsWeb
|
||||
? ""
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
"block_store"),
|
||||
delete: false,
|
||||
),
|
||||
network: VeilidConfigNetwork(
|
||||
connectionInitialTimeoutMs: 2000,
|
||||
connectionInactivityTimeoutMs: 60000,
|
||||
maxConnectionsPerIp4: 32,
|
||||
maxConnectionsPerIp6Prefix: 32,
|
||||
maxConnectionsPerIp6PrefixSize: 56,
|
||||
maxConnectionFrequencyPerMin: 128,
|
||||
clientWhitelistTimeoutMs: 300000,
|
||||
reverseConnectionReceiptTimeMs: 5000,
|
||||
holePunchReceiptTimeMs: 5000,
|
||||
routingTable: const VeilidConfigRoutingTable(
|
||||
nodeId: [],
|
||||
nodeIdSecret: [],
|
||||
bootstrap: kIsWeb
|
||||
? ["ws://bootstrap.veilid.net:5150/ws"]
|
||||
: ["bootstrap.veilid.net"],
|
||||
limitOverAttached: 64,
|
||||
limitFullyAttached: 32,
|
||||
limitAttachedStrong: 16,
|
||||
limitAttachedGood: 8,
|
||||
limitAttachedWeak: 4,
|
||||
Future<VeilidConfig> getDefaultVeilidConfig(String programName) async =>
|
||||
VeilidConfig(
|
||||
programName: programName,
|
||||
namespace: '',
|
||||
capabilities: const VeilidConfigCapabilities(disable: []),
|
||||
protectedStore: const VeilidConfigProtectedStore(
|
||||
allowInsecureFallback: false,
|
||||
alwaysUseInsecureStorage: false,
|
||||
directory: '',
|
||||
delete: false,
|
||||
deviceEncryptionKeyPassword: '',
|
||||
),
|
||||
rpc: const VeilidConfigRPC(
|
||||
concurrency: 0,
|
||||
queueSize: 1024,
|
||||
maxTimestampBehindMs: 10000,
|
||||
maxTimestampAheadMs: 10000,
|
||||
timeoutMs: 5000,
|
||||
maxRouteHopCount: 4,
|
||||
defaultRouteHopCount: 1,
|
||||
tableStore: VeilidConfigTableStore(
|
||||
directory: kIsWeb
|
||||
? ''
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
'table_store'),
|
||||
delete: false,
|
||||
),
|
||||
dht: VeilidConfigDHT(
|
||||
resolveNodeTimeoutMs: 10000,
|
||||
resolveNodeCount: 20,
|
||||
resolveNodeFanout: 3,
|
||||
maxFindNodeCount: 20,
|
||||
getValueTimeoutMs: 10000,
|
||||
getValueCount: 20,
|
||||
getValueFanout: 3,
|
||||
setValueTimeoutMs: 10000,
|
||||
setValueCount: 20,
|
||||
setValueFanout: 5,
|
||||
minPeerCount: 20,
|
||||
minPeerRefreshTimeMs: 60000,
|
||||
validateDialInfoReceiptTimeMs: 2000,
|
||||
localSubkeyCacheSize: getLocalSubkeyCacheSize(),
|
||||
localMaxSubkeyCacheMemoryMb: getLocalMaxSubkeyCacheMemoryMb(),
|
||||
remoteSubkeyCacheSize: getRemoteSubkeyCacheSize(),
|
||||
remoteMaxRecords: getRemoteMaxRecords(),
|
||||
remoteMaxSubkeyCacheMemoryMb: getRemoteMaxSubkeyCacheMemoryMb(),
|
||||
remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb()),
|
||||
upnp: true,
|
||||
detectAddressChanges: true,
|
||||
restrictedNatRetries: 0,
|
||||
tls: const VeilidConfigTLS(
|
||||
certificatePath: "",
|
||||
privateKeyPath: "",
|
||||
blockStore: VeilidConfigBlockStore(
|
||||
directory: kIsWeb
|
||||
? ''
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
'block_store'),
|
||||
delete: false,
|
||||
),
|
||||
network: VeilidConfigNetwork(
|
||||
connectionInitialTimeoutMs: 2000,
|
||||
),
|
||||
application: const VeilidConfigApplication(
|
||||
https: VeilidConfigHTTPS(
|
||||
enabled: false,
|
||||
listenAddress: "",
|
||||
path: "",
|
||||
url: null,
|
||||
connectionInactivityTimeoutMs: 60000,
|
||||
maxConnectionsPerIp4: 32,
|
||||
maxConnectionsPerIp6Prefix: 32,
|
||||
maxConnectionsPerIp6PrefixSize: 56,
|
||||
maxConnectionFrequencyPerMin: 128,
|
||||
clientWhitelistTimeoutMs: 300000,
|
||||
reverseConnectionReceiptTimeMs: 5000,
|
||||
holePunchReceiptTimeMs: 5000,
|
||||
routingTable: const VeilidConfigRoutingTable(
|
||||
nodeId: [],
|
||||
nodeIdSecret: [],
|
||||
bootstrap: kIsWeb
|
||||
? ['ws://bootstrap.veilid.net:5150/ws']
|
||||
: ['bootstrap.veilid.net'],
|
||||
limitOverAttached: 64,
|
||||
limitFullyAttached: 32,
|
||||
limitAttachedStrong: 16,
|
||||
limitAttachedGood: 8,
|
||||
limitAttachedWeak: 4,
|
||||
),
|
||||
rpc: const VeilidConfigRPC(
|
||||
concurrency: 0,
|
||||
queueSize: 1024,
|
||||
maxTimestampBehindMs: 10000,
|
||||
maxTimestampAheadMs: 10000,
|
||||
timeoutMs: 5000,
|
||||
maxRouteHopCount: 4,
|
||||
defaultRouteHopCount: 1,
|
||||
),
|
||||
dht: VeilidConfigDHT(
|
||||
resolveNodeTimeoutMs: 10000,
|
||||
resolveNodeCount: 20,
|
||||
resolveNodeFanout: 3,
|
||||
maxFindNodeCount: 20,
|
||||
getValueTimeoutMs: 10000,
|
||||
getValueCount: 20,
|
||||
getValueFanout: 3,
|
||||
setValueTimeoutMs: 10000,
|
||||
setValueCount: 20,
|
||||
setValueFanout: 5,
|
||||
minPeerCount: 20,
|
||||
minPeerRefreshTimeMs: 60000,
|
||||
validateDialInfoReceiptTimeMs: 2000,
|
||||
localSubkeyCacheSize: getLocalSubkeyCacheSize(),
|
||||
localMaxSubkeyCacheMemoryMb: await getLocalMaxSubkeyCacheMemoryMb(),
|
||||
remoteSubkeyCacheSize: getRemoteSubkeyCacheSize(),
|
||||
remoteMaxRecords: getRemoteMaxRecords(),
|
||||
remoteMaxSubkeyCacheMemoryMb:
|
||||
await getRemoteMaxSubkeyCacheMemoryMb(),
|
||||
remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb()),
|
||||
upnp: true,
|
||||
detectAddressChanges: true,
|
||||
restrictedNatRetries: 0,
|
||||
tls: const VeilidConfigTLS(
|
||||
certificatePath: '',
|
||||
privateKeyPath: '',
|
||||
connectionInitialTimeoutMs: 2000,
|
||||
),
|
||||
application: const VeilidConfigApplication(
|
||||
https: VeilidConfigHTTPS(
|
||||
enabled: false,
|
||||
listenAddress: '',
|
||||
path: '',
|
||||
),
|
||||
http: VeilidConfigHTTP(
|
||||
enabled: false,
|
||||
listenAddress: '',
|
||||
path: '',
|
||||
)),
|
||||
protocol: const VeilidConfigProtocol(
|
||||
udp: VeilidConfigUDP(
|
||||
enabled: !kIsWeb,
|
||||
socketPoolSize: 0,
|
||||
listenAddress: '',
|
||||
),
|
||||
tcp: VeilidConfigTCP(
|
||||
connect: !kIsWeb,
|
||||
listen: !kIsWeb,
|
||||
maxConnections: 32,
|
||||
listenAddress: '',
|
||||
),
|
||||
ws: VeilidConfigWS(
|
||||
connect: true,
|
||||
listen: !kIsWeb,
|
||||
maxConnections: 16,
|
||||
listenAddress: '',
|
||||
path: 'ws',
|
||||
),
|
||||
wss: VeilidConfigWSS(
|
||||
connect: true,
|
||||
listen: false,
|
||||
maxConnections: 16,
|
||||
listenAddress: '',
|
||||
path: 'ws',
|
||||
),
|
||||
http: VeilidConfigHTTP(
|
||||
enabled: false,
|
||||
listenAddress: "",
|
||||
path: "",
|
||||
url: null,
|
||||
)),
|
||||
protocol: const VeilidConfigProtocol(
|
||||
udp: VeilidConfigUDP(
|
||||
enabled: !kIsWeb,
|
||||
socketPoolSize: 0,
|
||||
listenAddress: "",
|
||||
publicAddress: null,
|
||||
),
|
||||
tcp: VeilidConfigTCP(
|
||||
connect: !kIsWeb,
|
||||
listen: !kIsWeb,
|
||||
maxConnections: 32,
|
||||
listenAddress: "",
|
||||
publicAddress: null,
|
||||
),
|
||||
ws: VeilidConfigWS(
|
||||
connect: true,
|
||||
listen: !kIsWeb,
|
||||
maxConnections: 16,
|
||||
listenAddress: "",
|
||||
path: "ws",
|
||||
url: null,
|
||||
),
|
||||
wss: VeilidConfigWSS(
|
||||
connect: true,
|
||||
listen: false,
|
||||
maxConnections: 16,
|
||||
listenAddress: "",
|
||||
path: "ws",
|
||||
url: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -5,7 +5,6 @@ import 'package:change_case/change_case.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'veilid_encoding.dart';
|
||||
import 'veilid.dart';
|
||||
|
||||
part 'routing_context.freezed.dart';
|
||||
@ -27,7 +26,7 @@ extension ValidateDFLT on DHTSchemaDFLT {
|
||||
|
||||
extension ValidateSMPL on DHTSchemaSMPL {
|
||||
bool validate() {
|
||||
final totalsv = members.fold(0, (acc, v) => (acc + v.mCnt)) + oCnt;
|
||||
final totalsv = members.fold(0, (acc, v) => acc + v.mCnt) + oCnt;
|
||||
if (totalsv > 65535) {
|
||||
return false;
|
||||
}
|
||||
@ -51,8 +50,8 @@ sealed class DHTSchema with _$DHTSchema {
|
||||
{required int oCnt,
|
||||
required List<DHTSchemaMember> members}) = DHTSchemaSMPL;
|
||||
|
||||
factory DHTSchema.fromJson(Map<String, dynamic> json) =>
|
||||
_$DHTSchemaFromJson(json);
|
||||
factory DHTSchema.fromJson(dynamic json) =>
|
||||
_$DHTSchemaFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
const DHTSchema defaultDHTSchema = DHTSchema.dflt(oCnt: 1);
|
||||
@ -65,8 +64,8 @@ class DHTSchemaMember with _$DHTSchemaMember {
|
||||
required int mCnt,
|
||||
}) = _DHTSchemaMember;
|
||||
|
||||
factory DHTSchemaMember.fromJson(Map<String, dynamic> json) =>
|
||||
_$DHTSchemaMemberFromJson(json);
|
||||
factory DHTSchemaMember.fromJson(dynamic json) =>
|
||||
_$DHTSchemaMemberFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -77,11 +76,27 @@ class DHTRecordDescriptor with _$DHTRecordDescriptor {
|
||||
const factory DHTRecordDescriptor({
|
||||
required TypedKey key,
|
||||
required PublicKey owner,
|
||||
PublicKey? ownerSecret,
|
||||
required DHTSchema schema,
|
||||
PublicKey? ownerSecret,
|
||||
}) = _DHTRecordDescriptor;
|
||||
factory DHTRecordDescriptor.fromJson(Map<String, dynamic> json) =>
|
||||
_$DHTRecordDescriptorFromJson(json);
|
||||
factory DHTRecordDescriptor.fromJson(dynamic json) =>
|
||||
_$DHTRecordDescriptorFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
extension DHTRecordDescriptorExt on DHTRecordDescriptor {
|
||||
KeyPair? ownerKeyPair() {
|
||||
if (ownerSecret == null) {
|
||||
return null;
|
||||
}
|
||||
return KeyPair(key: owner, secret: ownerSecret!);
|
||||
}
|
||||
|
||||
TypedKeyPair? ownerTypedKeyPair() {
|
||||
if (ownerSecret == null) {
|
||||
return null;
|
||||
}
|
||||
return TypedKeyPair(kind: key.kind, key: owner, secret: ownerSecret!);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -96,8 +111,8 @@ class ValueSubkeyRange with _$ValueSubkeyRange {
|
||||
required int high,
|
||||
}) = _ValueSubkeyRange;
|
||||
|
||||
factory ValueSubkeyRange.fromJson(Map<String, dynamic> json) =>
|
||||
_$ValueSubkeyRangeFromJson(json);
|
||||
factory ValueSubkeyRange.fromJson(dynamic json) =>
|
||||
_$ValueSubkeyRangeFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -112,8 +127,8 @@ class ValueData with _$ValueData {
|
||||
required PublicKey writer,
|
||||
}) = _ValueData;
|
||||
|
||||
factory ValueData.fromJson(Map<String, dynamic> json) =>
|
||||
_$ValueDataFromJson(json);
|
||||
factory ValueData.fromJson(dynamic json) =>
|
||||
_$ValueDataFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -123,9 +138,9 @@ enum Stability {
|
||||
lowLatency,
|
||||
reliable;
|
||||
|
||||
factory Stability.fromJson(dynamic j) =>
|
||||
Stability.values.byName((j as String).toCamelCase());
|
||||
String toJson() => name.toPascalCase();
|
||||
factory Stability.fromJson(String j) =>
|
||||
Stability.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -136,79 +151,74 @@ enum Sequencing {
|
||||
preferOrdered,
|
||||
ensureOrdered;
|
||||
|
||||
factory Sequencing.fromJson(dynamic j) =>
|
||||
Sequencing.values.byName((j as String).toCamelCase());
|
||||
String toJson() => name.toPascalCase();
|
||||
factory Sequencing.fromJson(String j) =>
|
||||
Sequencing.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// SafetySelection
|
||||
|
||||
@immutable
|
||||
abstract class SafetySelection extends Equatable {
|
||||
factory SafetySelection.fromJson(Map<String, dynamic> json) {
|
||||
if (json.containsKey("Unsafe")) {
|
||||
abstract class SafetySelection {
|
||||
factory SafetySelection.fromJson(dynamic jsond) {
|
||||
final json = jsond as Map<String, dynamic>;
|
||||
if (json.containsKey('Unsafe')) {
|
||||
return SafetySelectionUnsafe(
|
||||
sequencing: Sequencing.fromJson(json["Unsafe"]));
|
||||
} else if (json.containsKey("Safe")) {
|
||||
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(json["Safe"]));
|
||||
sequencing: Sequencing.fromJson(json['Unsafe']));
|
||||
} else if (json.containsKey('Safe')) {
|
||||
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(json['Safe']));
|
||||
} else {
|
||||
throw const VeilidAPIExceptionInternal("Invalid SafetySelection");
|
||||
throw const VeilidAPIExceptionInternal('Invalid SafetySelection');
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> toJson();
|
||||
}
|
||||
|
||||
@immutable
|
||||
class SafetySelectionUnsafe implements SafetySelection {
|
||||
class SafetySelectionUnsafe extends Equatable implements SafetySelection {
|
||||
//
|
||||
const SafetySelectionUnsafe({
|
||||
required this.sequencing,
|
||||
});
|
||||
final Sequencing sequencing;
|
||||
@override
|
||||
List<Object> get props => [sequencing];
|
||||
@override
|
||||
bool? get stringify => null;
|
||||
|
||||
//
|
||||
const SafetySelectionUnsafe({
|
||||
required this.sequencing,
|
||||
});
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'Unsafe': sequencing.toJson()};
|
||||
}
|
||||
Map<String, dynamic> toJson() => {'Unsafe': sequencing.toJson()};
|
||||
}
|
||||
|
||||
@immutable
|
||||
class SafetySelectionSafe implements SafetySelection {
|
||||
class SafetySelectionSafe extends Equatable implements SafetySelection {
|
||||
//
|
||||
const SafetySelectionSafe({
|
||||
required this.safetySpec,
|
||||
});
|
||||
final SafetySpec safetySpec;
|
||||
@override
|
||||
List<Object> get props => [safetySpec];
|
||||
@override
|
||||
bool? get stringify => null;
|
||||
|
||||
//
|
||||
const SafetySelectionSafe({
|
||||
required this.safetySpec,
|
||||
});
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'Safe': safetySpec.toJson()};
|
||||
}
|
||||
Map<String, dynamic> toJson() => {'Safe': safetySpec.toJson()};
|
||||
}
|
||||
|
||||
/// Options for safety routes (sender privacy)
|
||||
@freezed
|
||||
class SafetySpec with _$SafetySpec {
|
||||
const factory SafetySpec({
|
||||
String? preferredRoute,
|
||||
required int hopCount,
|
||||
required Stability stability,
|
||||
required Sequencing sequencing,
|
||||
String? preferredRoute,
|
||||
}) = _SafetySpec;
|
||||
|
||||
factory SafetySpec.fromJson(Map<String, dynamic> json) =>
|
||||
_$SafetySpecFromJson(json);
|
||||
factory SafetySpec.fromJson(dynamic json) =>
|
||||
_$SafetySpecFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -218,8 +228,8 @@ class RouteBlob with _$RouteBlob {
|
||||
const factory RouteBlob(
|
||||
{required String routeId,
|
||||
@Uint8ListJsonConverter() required Uint8List blob}) = _RouteBlob;
|
||||
factory RouteBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$RouteBlobFromJson(json);
|
||||
factory RouteBlob.fromJson(dynamic json) =>
|
||||
_$RouteBlobFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
@ -4,28 +4,26 @@ import 'dart:typed_data';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'veilid_stub.dart'
|
||||
if (dart.library.io) 'veilid_ffi.dart'
|
||||
if (dart.library.js) 'veilid_js.dart';
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
import 'routing_context.dart';
|
||||
import 'veilid_config.dart';
|
||||
import 'veilid_crypto.dart';
|
||||
import 'veilid_table_db.dart';
|
||||
import 'veilid_state.dart';
|
||||
import 'veilid_stub.dart'
|
||||
if (dart.library.io) 'veilid_ffi.dart'
|
||||
if (dart.library.js) 'veilid_js.dart';
|
||||
import 'veilid_table_db.dart';
|
||||
|
||||
export 'default_config.dart';
|
||||
export 'routing_context.dart';
|
||||
|
||||
export 'veilid_encoding.dart';
|
||||
export 'veilid.dart';
|
||||
export 'veilid_api_exception.dart';
|
||||
export 'veilid_config.dart';
|
||||
export 'veilid_crypto.dart';
|
||||
export 'veilid_table_db.dart';
|
||||
export 'veilid_api_exception.dart';
|
||||
export 'veilid_encoding.dart';
|
||||
export 'veilid_state.dart';
|
||||
export 'veilid.dart';
|
||||
export 'veilid_table_db.dart';
|
||||
|
||||
//////////////////////////////////////
|
||||
/// JSON Encode Helper
|
||||
@ -41,57 +39,39 @@ Object? veilidApiToEncodable(Object? value) {
|
||||
throw UnsupportedError('Cannot convert to JSON: $value');
|
||||
}
|
||||
|
||||
T? Function(dynamic) optFromJson<T>(
|
||||
T Function(Map<String, dynamic>) jsonConstructor) {
|
||||
return (dynamic j) {
|
||||
if (j == null) {
|
||||
return null;
|
||||
} else {
|
||||
return jsonConstructor(j);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
List<T> Function(dynamic) jsonListConstructor<T>(
|
||||
T Function(Map<String, dynamic>) jsonConstructor) {
|
||||
return (dynamic j) {
|
||||
return (j as List<Map<String, dynamic>>)
|
||||
.map((e) => jsonConstructor(e))
|
||||
.toList();
|
||||
};
|
||||
}
|
||||
T Function(dynamic) jsonConstructor) =>
|
||||
(dynamic j) => (j as List<dynamic>).map((e) => jsonConstructor(e)).toList();
|
||||
|
||||
//////////////////////////////////////
|
||||
/// VeilidVersion
|
||||
|
||||
@immutable
|
||||
class VeilidVersion extends Equatable {
|
||||
const VeilidVersion(this.major, this.minor, this.patch);
|
||||
final int major;
|
||||
final int minor;
|
||||
final int patch;
|
||||
@override
|
||||
List<Object> get props => [major, minor, patch];
|
||||
|
||||
const VeilidVersion(this.major, this.minor, this.patch);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// Timestamp
|
||||
@immutable
|
||||
class Timestamp extends Equatable {
|
||||
const Timestamp({required this.value});
|
||||
factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s));
|
||||
factory Timestamp.fromJson(dynamic json) =>
|
||||
Timestamp.fromString(json as String);
|
||||
final BigInt value;
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
|
||||
const Timestamp({required this.value});
|
||||
|
||||
@override
|
||||
String toString() => value.toString();
|
||||
factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s));
|
||||
|
||||
String toJson() => toString();
|
||||
factory Timestamp.fromJson(dynamic json) =>
|
||||
Timestamp.fromString(json as String);
|
||||
|
||||
TimestampDuration diff(Timestamp other) =>
|
||||
TimestampDuration(value: value - other.value);
|
||||
@ -102,20 +82,19 @@ class Timestamp extends Equatable {
|
||||
|
||||
@immutable
|
||||
class TimestampDuration extends Equatable {
|
||||
const TimestampDuration({required this.value});
|
||||
factory TimestampDuration.fromString(String s) =>
|
||||
TimestampDuration(value: BigInt.parse(s));
|
||||
factory TimestampDuration.fromJson(dynamic json) =>
|
||||
TimestampDuration.fromString(json as String);
|
||||
final BigInt value;
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
|
||||
const TimestampDuration({required this.value});
|
||||
|
||||
@override
|
||||
String toString() => value.toString();
|
||||
factory TimestampDuration.fromString(String s) =>
|
||||
TimestampDuration(value: BigInt.parse(s));
|
||||
|
||||
String toJson() => toString();
|
||||
factory TimestampDuration.fromJson(dynamic json) =>
|
||||
TimestampDuration.fromString(json as String);
|
||||
|
||||
int toMillis() => (value ~/ BigInt.from(1000)).toInt();
|
||||
BigInt toMicros() => value;
|
||||
@ -156,7 +135,7 @@ abstract class Veilid {
|
||||
Future<void> releasePrivateRoute(String key);
|
||||
|
||||
// App calls
|
||||
Future<void> appCallReply(String id, Uint8List message);
|
||||
Future<void> appCallReply(String callId, Uint8List message);
|
||||
|
||||
// TableStore
|
||||
Future<VeilidTableDB> openTableDB(String name, int columnCount);
|
||||
|
@ -5,70 +5,73 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@immutable
|
||||
abstract class VeilidAPIException implements Exception {
|
||||
factory VeilidAPIException.fromJson(dynamic json) {
|
||||
switch (json["kind"]) {
|
||||
case "NotInitialized":
|
||||
factory VeilidAPIException.fromJson(dynamic j) {
|
||||
final json = j as Map<String, dynamic>;
|
||||
switch (json['kind']! as String) {
|
||||
case 'NotInitialized':
|
||||
{
|
||||
return VeilidAPIExceptionNotInitialized();
|
||||
}
|
||||
case "AlreadyInitialized":
|
||||
case 'AlreadyInitialized':
|
||||
{
|
||||
return VeilidAPIExceptionAlreadyInitialized();
|
||||
}
|
||||
case "Timeout":
|
||||
case 'Timeout':
|
||||
{
|
||||
return VeilidAPIExceptionTimeout();
|
||||
}
|
||||
case "TryAgain":
|
||||
case 'TryAgain':
|
||||
{
|
||||
return VeilidAPIExceptionTryAgain();
|
||||
}
|
||||
case "Shutdown":
|
||||
case 'Shutdown':
|
||||
{
|
||||
return VeilidAPIExceptionShutdown();
|
||||
}
|
||||
case "InvalidTarget":
|
||||
case 'InvalidTarget':
|
||||
{
|
||||
return VeilidAPIExceptionInvalidTarget();
|
||||
}
|
||||
case "NoConnection":
|
||||
case 'NoConnection':
|
||||
{
|
||||
return VeilidAPIExceptionNoConnection(json["message"]);
|
||||
return VeilidAPIExceptionNoConnection(json['message']! as String);
|
||||
}
|
||||
case "KeyNotFound":
|
||||
case 'KeyNotFound':
|
||||
{
|
||||
return VeilidAPIExceptionKeyNotFound(json["key"]);
|
||||
return VeilidAPIExceptionKeyNotFound(json['key']! as String);
|
||||
}
|
||||
case "Internal":
|
||||
case 'Internal':
|
||||
{
|
||||
return VeilidAPIExceptionInternal(json["message"]);
|
||||
return VeilidAPIExceptionInternal(json['message']! as String);
|
||||
}
|
||||
case "Unimplemented":
|
||||
case 'Unimplemented':
|
||||
{
|
||||
return VeilidAPIExceptionUnimplemented(json["unimplemented"]);
|
||||
return VeilidAPIExceptionUnimplemented(
|
||||
json['unimplemented']! as String);
|
||||
}
|
||||
case "ParseError":
|
||||
case 'ParseError':
|
||||
{
|
||||
return VeilidAPIExceptionParseError(json["message"], json["value"]);
|
||||
return VeilidAPIExceptionParseError(
|
||||
json['message']! as String, json['value']! as String);
|
||||
}
|
||||
case "InvalidArgument":
|
||||
case 'InvalidArgument':
|
||||
{
|
||||
return VeilidAPIExceptionInvalidArgument(
|
||||
json["context"], json["argument"], json["value"]);
|
||||
return VeilidAPIExceptionInvalidArgument(json['context']! as String,
|
||||
json['argument']! as String, json['value']! as String);
|
||||
}
|
||||
case "MissingArgument":
|
||||
case 'MissingArgument':
|
||||
{
|
||||
return VeilidAPIExceptionMissingArgument(
|
||||
json["context"], json["argument"]);
|
||||
json['context']! as String, json['argument']! as String);
|
||||
}
|
||||
case "Generic":
|
||||
case 'Generic':
|
||||
{
|
||||
return VeilidAPIExceptionGeneric(json["message"]);
|
||||
return VeilidAPIExceptionGeneric(json['message']! as String);
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw VeilidAPIExceptionInternal(
|
||||
"Invalid VeilidAPIException type: ${json['kind']}");
|
||||
"Invalid VeilidAPIException type: ${json['kind']! as String}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,224 +82,163 @@ abstract class VeilidAPIException implements Exception {
|
||||
@immutable
|
||||
class VeilidAPIExceptionNotInitialized implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: NotInitialized";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: NotInitialized';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Not initialized";
|
||||
}
|
||||
String toDisplayError() => 'Not initialized';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: AlreadyInitialized";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: AlreadyInitialized';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Already initialized";
|
||||
}
|
||||
String toDisplayError() => 'Already initialized';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionTimeout implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: Timeout";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: Timeout';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Timeout";
|
||||
}
|
||||
String toDisplayError() => 'Timeout';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionTryAgain implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: TryAgain";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: TryAgain';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Try again";
|
||||
}
|
||||
String toDisplayError() => 'Try again';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionShutdown implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: Shutdown";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: Shutdown';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Currently shut down";
|
||||
}
|
||||
String toDisplayError() => 'Currently shut down';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionInvalidTarget implements VeilidAPIException {
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: InvalidTarget";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: InvalidTarget';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Invalid target";
|
||||
}
|
||||
String toDisplayError() => 'Invalid target';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionNoConnection implements VeilidAPIException {
|
||||
final String message;
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: NoConnection (message: $message)";
|
||||
}
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "No connection: $message";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionNoConnection(this.message);
|
||||
final String message;
|
||||
@override
|
||||
String toString() => 'VeilidAPIException: NoConnection (message: $message)';
|
||||
|
||||
@override
|
||||
String toDisplayError() => 'No connection: $message';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionKeyNotFound implements VeilidAPIException {
|
||||
final String key;
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: KeyNotFound (key: $key)";
|
||||
}
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Key not found: $key";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionKeyNotFound(this.key);
|
||||
final String key;
|
||||
@override
|
||||
String toString() => 'VeilidAPIException: KeyNotFound (key: $key)';
|
||||
|
||||
@override
|
||||
String toDisplayError() => 'Key not found: $key';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionInternal implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionInternal(this.message);
|
||||
final String message;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: Internal ($message)";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: Internal ($message)';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Internal error: $message";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionInternal(this.message);
|
||||
String toDisplayError() => 'Internal error: $message';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionUnimplemented(this.message);
|
||||
final String message;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: Unimplemented ($message)";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: Unimplemented ($message)';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Unimplemented: $message";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionUnimplemented(this.message);
|
||||
String toDisplayError() => 'Unimplemented: $message';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionParseError implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionParseError(this.message, this.value);
|
||||
final String message;
|
||||
final String value;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: ParseError ($message)\n value: $value";
|
||||
}
|
||||
String toString() =>
|
||||
'VeilidAPIException: ParseError ($message)\n value: $value';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Parse error: $message";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionParseError(this.message, this.value);
|
||||
String toDisplayError() => 'Parse error: $message';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionInvalidArgument(
|
||||
this.context, this.argument, this.value);
|
||||
final String context;
|
||||
final String argument;
|
||||
final String value;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: InvalidArgument'
|
||||
' ($context:$argument)\n value: $value';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Invalid argument for $context: $argument";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionInvalidArgument(
|
||||
this.context, this.argument, this.value);
|
||||
String toDisplayError() => 'Invalid argument for $context: $argument';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
|
||||
final String context;
|
||||
final String argument;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: MissingArgument ($context:$argument)";
|
||||
}
|
||||
String toString() =>
|
||||
'VeilidAPIException: MissingArgument ($context:$argument)';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return "Missing argument for $context: $argument";
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
|
||||
String toDisplayError() => 'Missing argument for $context: $argument';
|
||||
}
|
||||
|
||||
@immutable
|
||||
class VeilidAPIExceptionGeneric implements VeilidAPIException {
|
||||
//
|
||||
const VeilidAPIExceptionGeneric(this.message);
|
||||
final String message;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "VeilidAPIException: Generic (message: $message)";
|
||||
}
|
||||
String toString() => 'VeilidAPIException: Generic (message: $message)';
|
||||
|
||||
@override
|
||||
String toDisplayError() {
|
||||
return message;
|
||||
}
|
||||
|
||||
//
|
||||
const VeilidAPIExceptionGeneric(this.message);
|
||||
String toDisplayError() => message;
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:change_case/change_case.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'veilid.dart';
|
||||
import 'veilid_encoding.dart';
|
||||
import 'veilid_crypto.dart';
|
||||
|
||||
part 'veilid_config.freezed.dart';
|
||||
part 'veilid_config.g.dart';
|
||||
@ -17,8 +16,8 @@ class VeilidFFIConfigLoggingTerminal with _$VeilidFFIConfigLoggingTerminal {
|
||||
required VeilidConfigLogLevel level,
|
||||
}) = _VeilidFFIConfigLoggingTerminal;
|
||||
|
||||
factory VeilidFFIConfigLoggingTerminal.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidFFIConfigLoggingTerminalFromJson(json);
|
||||
factory VeilidFFIConfigLoggingTerminal.fromJson(dynamic json) =>
|
||||
_$VeilidFFIConfigLoggingTerminalFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -30,8 +29,8 @@ class VeilidFFIConfigLoggingOtlp with _$VeilidFFIConfigLoggingOtlp {
|
||||
required String serviceName,
|
||||
}) = _VeilidFFIConfigLoggingOtlp;
|
||||
|
||||
factory VeilidFFIConfigLoggingOtlp.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidFFIConfigLoggingOtlpFromJson(json);
|
||||
factory VeilidFFIConfigLoggingOtlp.fromJson(dynamic json) =>
|
||||
_$VeilidFFIConfigLoggingOtlpFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -41,8 +40,8 @@ class VeilidFFIConfigLoggingApi with _$VeilidFFIConfigLoggingApi {
|
||||
required VeilidConfigLogLevel level,
|
||||
}) = _VeilidFFIConfigLoggingApi;
|
||||
|
||||
factory VeilidFFIConfigLoggingApi.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidFFIConfigLoggingApiFromJson(json);
|
||||
factory VeilidFFIConfigLoggingApi.fromJson(dynamic json) =>
|
||||
_$VeilidFFIConfigLoggingApiFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -52,8 +51,8 @@ class VeilidFFIConfigLogging with _$VeilidFFIConfigLogging {
|
||||
required VeilidFFIConfigLoggingOtlp otlp,
|
||||
required VeilidFFIConfigLoggingApi api}) = _VeilidFFIConfigLogging;
|
||||
|
||||
factory VeilidFFIConfigLogging.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidFFIConfigLoggingFromJson(json);
|
||||
factory VeilidFFIConfigLogging.fromJson(dynamic json) =>
|
||||
_$VeilidFFIConfigLoggingFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -62,8 +61,8 @@ class VeilidFFIConfig with _$VeilidFFIConfig {
|
||||
required VeilidFFIConfigLogging logging,
|
||||
}) = _VeilidFFIConfig;
|
||||
|
||||
factory VeilidFFIConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidFFIConfigFromJson(json);
|
||||
factory VeilidFFIConfig.fromJson(dynamic json) =>
|
||||
_$VeilidFFIConfigFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
@ -79,9 +78,9 @@ class VeilidWASMConfigLoggingPerformance
|
||||
required bool logsInConsole,
|
||||
}) = _VeilidWASMConfigLoggingPerformance;
|
||||
|
||||
factory VeilidWASMConfigLoggingPerformance.fromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$VeilidWASMConfigLoggingPerformanceFromJson(json);
|
||||
factory VeilidWASMConfigLoggingPerformance.fromJson(dynamic json) =>
|
||||
_$VeilidWASMConfigLoggingPerformanceFromJson(
|
||||
json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -91,8 +90,8 @@ class VeilidWASMConfigLoggingApi with _$VeilidWASMConfigLoggingApi {
|
||||
required VeilidConfigLogLevel level,
|
||||
}) = _VeilidWASMConfigLoggingApi;
|
||||
|
||||
factory VeilidWASMConfigLoggingApi.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidWASMConfigLoggingApiFromJson(json);
|
||||
factory VeilidWASMConfigLoggingApi.fromJson(dynamic json) =>
|
||||
_$VeilidWASMConfigLoggingApiFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -101,8 +100,8 @@ class VeilidWASMConfigLogging with _$VeilidWASMConfigLogging {
|
||||
{required VeilidWASMConfigLoggingPerformance performance,
|
||||
required VeilidWASMConfigLoggingApi api}) = _VeilidWASMConfigLogging;
|
||||
|
||||
factory VeilidWASMConfigLogging.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidWASMConfigLoggingFromJson(json);
|
||||
factory VeilidWASMConfigLogging.fromJson(dynamic json) =>
|
||||
_$VeilidWASMConfigLoggingFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -111,8 +110,8 @@ class VeilidWASMConfig with _$VeilidWASMConfig {
|
||||
required VeilidWASMConfigLogging logging,
|
||||
}) = _VeilidWASMConfig;
|
||||
|
||||
factory VeilidWASMConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidWASMConfigFromJson(json);
|
||||
factory VeilidWASMConfig.fromJson(dynamic json) =>
|
||||
_$VeilidWASMConfigFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -126,13 +125,9 @@ enum VeilidConfigLogLevel {
|
||||
debug,
|
||||
trace;
|
||||
|
||||
String toJson() {
|
||||
return name.toPascalCase();
|
||||
}
|
||||
|
||||
factory VeilidConfigLogLevel.fromJson(dynamic j) {
|
||||
return VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
|
||||
}
|
||||
factory VeilidConfigLogLevel.fromJson(dynamic j) =>
|
||||
VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
|
||||
String toJson() => name.toPascalCase();
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -147,8 +142,8 @@ class VeilidConfigHTTPS with _$VeilidConfigHTTPS {
|
||||
String? url,
|
||||
}) = _VeilidConfigHTTPS;
|
||||
|
||||
factory VeilidConfigHTTPS.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigHTTPSFromJson(json);
|
||||
factory VeilidConfigHTTPS.fromJson(dynamic json) =>
|
||||
_$VeilidConfigHTTPSFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -162,8 +157,8 @@ class VeilidConfigHTTP with _$VeilidConfigHTTP {
|
||||
String? url,
|
||||
}) = _VeilidConfigHTTP;
|
||||
|
||||
factory VeilidConfigHTTP.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigHTTPFromJson(json);
|
||||
factory VeilidConfigHTTP.fromJson(dynamic json) =>
|
||||
_$VeilidConfigHTTPFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -175,8 +170,8 @@ class VeilidConfigApplication with _$VeilidConfigApplication {
|
||||
required VeilidConfigHTTP http,
|
||||
}) = _VeilidConfigApplication;
|
||||
|
||||
factory VeilidConfigApplication.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigApplicationFromJson(json);
|
||||
factory VeilidConfigApplication.fromJson(dynamic json) =>
|
||||
_$VeilidConfigApplicationFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -188,8 +183,8 @@ class VeilidConfigUDP with _$VeilidConfigUDP {
|
||||
required String listenAddress,
|
||||
String? publicAddress}) = _VeilidConfigUDP;
|
||||
|
||||
factory VeilidConfigUDP.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigUDPFromJson(json);
|
||||
factory VeilidConfigUDP.fromJson(dynamic json) =>
|
||||
_$VeilidConfigUDPFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -202,8 +197,8 @@ class VeilidConfigTCP with _$VeilidConfigTCP {
|
||||
required String listenAddress,
|
||||
String? publicAddress}) = _VeilidConfigTCP;
|
||||
|
||||
factory VeilidConfigTCP.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigTCPFromJson(json);
|
||||
factory VeilidConfigTCP.fromJson(dynamic json) =>
|
||||
_$VeilidConfigTCPFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -217,8 +212,8 @@ class VeilidConfigWS with _$VeilidConfigWS {
|
||||
required String path,
|
||||
String? url}) = _VeilidConfigWS;
|
||||
|
||||
factory VeilidConfigWS.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigWSFromJson(json);
|
||||
factory VeilidConfigWS.fromJson(dynamic json) =>
|
||||
_$VeilidConfigWSFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -232,8 +227,8 @@ class VeilidConfigWSS with _$VeilidConfigWSS {
|
||||
required String path,
|
||||
String? url}) = _VeilidConfigWSS;
|
||||
|
||||
factory VeilidConfigWSS.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigWSSFromJson(json);
|
||||
factory VeilidConfigWSS.fromJson(dynamic json) =>
|
||||
_$VeilidConfigWSSFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -247,8 +242,8 @@ class VeilidConfigProtocol with _$VeilidConfigProtocol {
|
||||
required VeilidConfigWSS wss,
|
||||
}) = _VeilidConfigProtocol;
|
||||
|
||||
factory VeilidConfigProtocol.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigProtocolFromJson(json);
|
||||
factory VeilidConfigProtocol.fromJson(dynamic json) =>
|
||||
_$VeilidConfigProtocolFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -261,8 +256,8 @@ class VeilidConfigTLS with _$VeilidConfigTLS {
|
||||
required int connectionInitialTimeoutMs,
|
||||
}) = _VeilidConfigTLS;
|
||||
|
||||
factory VeilidConfigTLS.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigTLSFromJson(json);
|
||||
factory VeilidConfigTLS.fromJson(dynamic json) =>
|
||||
_$VeilidConfigTLSFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -289,8 +284,8 @@ class VeilidConfigDHT with _$VeilidConfigDHT {
|
||||
required int remoteMaxSubkeyCacheMemoryMb,
|
||||
required int remoteMaxStorageSpaceMb}) = _VeilidConfigDHT;
|
||||
|
||||
factory VeilidConfigDHT.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigDHTFromJson(json);
|
||||
factory VeilidConfigDHT.fromJson(dynamic json) =>
|
||||
_$VeilidConfigDHTFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -300,14 +295,14 @@ class VeilidConfigRPC with _$VeilidConfigRPC {
|
||||
const factory VeilidConfigRPC(
|
||||
{required int concurrency,
|
||||
required int queueSize,
|
||||
int? maxTimestampBehindMs,
|
||||
int? maxTimestampAheadMs,
|
||||
required int timeoutMs,
|
||||
required int maxRouteHopCount,
|
||||
required int defaultRouteHopCount}) = _VeilidConfigRPC;
|
||||
required int defaultRouteHopCount,
|
||||
int? maxTimestampBehindMs,
|
||||
int? maxTimestampAheadMs}) = _VeilidConfigRPC;
|
||||
|
||||
factory VeilidConfigRPC.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigRPCFromJson(json);
|
||||
factory VeilidConfigRPC.fromJson(dynamic json) =>
|
||||
_$VeilidConfigRPCFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -325,8 +320,8 @@ class VeilidConfigRoutingTable with _$VeilidConfigRoutingTable {
|
||||
required int limitAttachedWeak,
|
||||
}) = _VeilidConfigRoutingTable;
|
||||
|
||||
factory VeilidConfigRoutingTable.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigRoutingTableFromJson(json);
|
||||
factory VeilidConfigRoutingTable.fromJson(dynamic json) =>
|
||||
_$VeilidConfigRoutingTableFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -343,7 +338,6 @@ class VeilidConfigNetwork with _$VeilidConfigNetwork {
|
||||
required int clientWhitelistTimeoutMs,
|
||||
required int reverseConnectionReceiptTimeMs,
|
||||
required int holePunchReceiptTimeMs,
|
||||
String? networkKeyPassword,
|
||||
required VeilidConfigRoutingTable routingTable,
|
||||
required VeilidConfigRPC rpc,
|
||||
required VeilidConfigDHT dht,
|
||||
@ -353,10 +347,11 @@ class VeilidConfigNetwork with _$VeilidConfigNetwork {
|
||||
required VeilidConfigTLS tls,
|
||||
required VeilidConfigApplication application,
|
||||
required VeilidConfigProtocol protocol,
|
||||
String? networkKeyPassword,
|
||||
}) = _VeilidConfigNetwork;
|
||||
|
||||
factory VeilidConfigNetwork.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigNetworkFromJson(json);
|
||||
factory VeilidConfigNetwork.fromJson(dynamic json) =>
|
||||
_$VeilidConfigNetworkFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -368,8 +363,8 @@ class VeilidConfigTableStore with _$VeilidConfigTableStore {
|
||||
required bool delete,
|
||||
}) = _VeilidConfigTableStore;
|
||||
|
||||
factory VeilidConfigTableStore.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigTableStoreFromJson(json);
|
||||
factory VeilidConfigTableStore.fromJson(dynamic json) =>
|
||||
_$VeilidConfigTableStoreFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -381,8 +376,8 @@ class VeilidConfigBlockStore with _$VeilidConfigBlockStore {
|
||||
required bool delete,
|
||||
}) = _VeilidConfigBlockStore;
|
||||
|
||||
factory VeilidConfigBlockStore.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigBlockStoreFromJson(json);
|
||||
factory VeilidConfigBlockStore.fromJson(dynamic json) =>
|
||||
_$VeilidConfigBlockStoreFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -397,8 +392,8 @@ class VeilidConfigProtectedStore with _$VeilidConfigProtectedStore {
|
||||
required String deviceEncryptionKeyPassword,
|
||||
String? newDeviceEncryptionKeyPassword}) = _VeilidConfigProtectedStore;
|
||||
|
||||
factory VeilidConfigProtectedStore.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigProtectedStoreFromJson(json);
|
||||
factory VeilidConfigProtectedStore.fromJson(dynamic json) =>
|
||||
_$VeilidConfigProtectedStoreFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -409,8 +404,8 @@ class VeilidConfigCapabilities with _$VeilidConfigCapabilities {
|
||||
required List<String> disable,
|
||||
}) = _VeilidConfigCapabilities;
|
||||
|
||||
factory VeilidConfigCapabilities.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigCapabilitiesFromJson(json);
|
||||
factory VeilidConfigCapabilities.fromJson(dynamic json) =>
|
||||
_$VeilidConfigCapabilitiesFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -427,6 +422,6 @@ class VeilidConfig with _$VeilidConfig {
|
||||
required VeilidConfigNetwork network,
|
||||
}) = _VeilidConfig;
|
||||
|
||||
factory VeilidConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidConfigFromJson(json);
|
||||
factory VeilidConfig.fromJson(dynamic json) =>
|
||||
_$VeilidConfigFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import 'package:charcode/charcode.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'veilid_encoding.dart';
|
||||
import 'veilid.dart';
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -17,27 +16,23 @@ const CryptoKind cryptoKindVLD0 =
|
||||
const CryptoKind cryptoKindNONE =
|
||||
$N << 0 | $O << 8 | $N << 16 | $E << 24; // "NONE"
|
||||
|
||||
String cryptoKindToString(CryptoKind kind) {
|
||||
return "${String.fromCharCode(kind & 0xFF)}${String.fromCharCode((kind >> 8) & 0xFF)}${String.fromCharCode((kind >> 16) & 0xFF)}${String.fromCharCode((kind >> 24) & 0xFF)}";
|
||||
}
|
||||
String cryptoKindToString(CryptoKind kind) =>
|
||||
cryptoKindToBytes(kind).map(String.fromCharCode).join();
|
||||
|
||||
const CryptoKind bestCryptoKind = cryptoKindVLD0;
|
||||
|
||||
Uint8List cryptoKindToBytes(CryptoKind kind) {
|
||||
var b = Uint8List(4);
|
||||
b[0] = kind & 0xFF;
|
||||
b[1] = (kind >> 8) & 0xFF;
|
||||
b[2] = (kind >> 16) & 0xFF;
|
||||
b[3] = (kind >> 24) & 0xFF;
|
||||
final b = Uint8List(4);
|
||||
ByteData.sublistView(b).setUint32(0, kind);
|
||||
return b;
|
||||
}
|
||||
|
||||
CryptoKind cryptoKindFromString(String s) {
|
||||
if (s.codeUnits.length != 4) {
|
||||
throw const FormatException("malformed string");
|
||||
throw const FormatException('malformed string');
|
||||
}
|
||||
CryptoKind kind = s.codeUnits[0] |
|
||||
s.codeUnits[1] << 8 |
|
||||
s.codeUnits[2] << 16 |
|
||||
s.codeUnits[3] << 24;
|
||||
final kind =
|
||||
ByteData.sublistView(Uint8List.fromList(s.codeUnits)).getUint32(0);
|
||||
return kind;
|
||||
}
|
||||
|
||||
@ -46,100 +41,95 @@ CryptoKind cryptoKindFromString(String s) {
|
||||
|
||||
@immutable
|
||||
class Typed<V extends EncodedString> extends Equatable {
|
||||
const Typed({required this.kind, required this.value});
|
||||
|
||||
factory Typed.fromString(String s) {
|
||||
final parts = s.split(':');
|
||||
if (parts.length < 2 || parts[0].codeUnits.length != 4) {
|
||||
throw const FormatException('malformed string');
|
||||
}
|
||||
final kind = cryptoKindFromString(parts[0]);
|
||||
final value = EncodedString.fromString<V>(parts.sublist(1).join(':'));
|
||||
return Typed(kind: kind, value: value);
|
||||
}
|
||||
factory Typed.fromJson(dynamic json) => Typed.fromString(json as String);
|
||||
final CryptoKind kind;
|
||||
final V value;
|
||||
@override
|
||||
List<Object> get props => [kind, value];
|
||||
|
||||
const Typed({required this.kind, required this.value});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "${cryptoKindToString(kind)}:$value";
|
||||
}
|
||||
|
||||
factory Typed.fromString(String s) {
|
||||
final parts = s.split(":");
|
||||
if (parts.length < 2 || parts[0].codeUnits.length != 4) {
|
||||
throw const FormatException("malformed string");
|
||||
}
|
||||
final kind = cryptoKindFromString(parts[0]);
|
||||
final value = EncodedString.fromString<V>(parts.sublist(1).join(":"));
|
||||
return Typed(kind: kind, value: value);
|
||||
}
|
||||
String toString() => '${cryptoKindToString(kind)}:$value';
|
||||
|
||||
Uint8List decode() {
|
||||
var b = cryptoKindToBytes(kind);
|
||||
b.addAll(value.decode());
|
||||
return b;
|
||||
final b = BytesBuilder()
|
||||
..add(cryptoKindToBytes(kind))
|
||||
..add(value.decode());
|
||||
return b.toBytes();
|
||||
}
|
||||
|
||||
String toJson() => toString();
|
||||
factory Typed.fromJson(dynamic json) => Typed.fromString(json as String);
|
||||
}
|
||||
|
||||
@immutable
|
||||
class KeyPair extends Equatable {
|
||||
final PublicKey key;
|
||||
final PublicKey secret;
|
||||
@override
|
||||
List<Object> get props => [key, secret];
|
||||
|
||||
const KeyPair({required this.key, required this.secret});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "${key.toString()}:${secret.toString()}";
|
||||
}
|
||||
|
||||
factory KeyPair.fromString(String s) {
|
||||
final parts = s.split(":");
|
||||
final parts = s.split(':');
|
||||
if (parts.length != 2 ||
|
||||
parts[0].codeUnits.length != 43 ||
|
||||
parts[1].codeUnits.length != 43) {
|
||||
throw const FormatException("malformed string");
|
||||
throw const FormatException('malformed string');
|
||||
}
|
||||
final key = PublicKey.fromString(parts[0]);
|
||||
final secret = PublicKey.fromString(parts[1]);
|
||||
return KeyPair(key: key, secret: secret);
|
||||
}
|
||||
factory KeyPair.fromJson(dynamic json) => KeyPair.fromString(json as String);
|
||||
final PublicKey key;
|
||||
final PublicKey secret;
|
||||
@override
|
||||
List<Object> get props => [key, secret];
|
||||
|
||||
@override
|
||||
String toString() => '$key:$secret';
|
||||
|
||||
String toJson() => toString();
|
||||
factory KeyPair.fromJson(dynamic json) => KeyPair.fromString(json as String);
|
||||
}
|
||||
|
||||
@immutable
|
||||
class TypedKeyPair extends Equatable {
|
||||
final CryptoKind kind;
|
||||
final PublicKey key;
|
||||
final PublicKey secret;
|
||||
@override
|
||||
List<Object> get props => [kind, key, secret];
|
||||
|
||||
const TypedKeyPair(
|
||||
{required this.kind, required this.key, required this.secret});
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
"${cryptoKindToString(kind)}:${key.toString()}:${secret.toString()}";
|
||||
|
||||
factory TypedKeyPair.fromString(String s) {
|
||||
final parts = s.split(":");
|
||||
final parts = s.split(':');
|
||||
if (parts.length != 3 ||
|
||||
parts[0].codeUnits.length != 4 ||
|
||||
parts[1].codeUnits.length != 43 ||
|
||||
parts[2].codeUnits.length != 43) {
|
||||
throw VeilidAPIExceptionInvalidArgument("malformed string", "s", s);
|
||||
throw VeilidAPIExceptionInvalidArgument('malformed string', 's', s);
|
||||
}
|
||||
final kind = cryptoKindFromString(parts[0]);
|
||||
final key = PublicKey.fromString(parts[1]);
|
||||
final secret = PublicKey.fromString(parts[2]);
|
||||
return TypedKeyPair(kind: kind, key: key, secret: secret);
|
||||
}
|
||||
|
||||
String toJson() => toString();
|
||||
factory TypedKeyPair.fromJson(dynamic json) =>
|
||||
TypedKeyPair.fromString(json as String);
|
||||
factory TypedKeyPair.fromKeyPair(CryptoKind kind, KeyPair keyPair) =>
|
||||
TypedKeyPair(kind: kind, key: keyPair.key, secret: keyPair.secret);
|
||||
final CryptoKind kind;
|
||||
final PublicKey key;
|
||||
final PublicKey secret;
|
||||
@override
|
||||
List<Object> get props => [kind, key, secret];
|
||||
|
||||
@override
|
||||
String toString() => '${cryptoKindToString(kind)}:$key:$secret';
|
||||
|
||||
String toJson() => toString();
|
||||
}
|
||||
|
||||
typedef CryptoKey = FixedEncodedString43;
|
||||
@ -176,17 +166,15 @@ abstract class VeilidCryptoSystem {
|
||||
Future<HashDigest> generateHash(Uint8List data);
|
||||
//Future<HashDigest> generateHashReader(Stream<List<int>> reader);
|
||||
Future<bool> validateKeyPair(PublicKey key, SecretKey secret);
|
||||
Future<bool> validateKeyPairWithKeyPair(KeyPair keyPair) {
|
||||
return validateKeyPair(keyPair.key, keyPair.secret);
|
||||
}
|
||||
Future<bool> validateKeyPairWithKeyPair(KeyPair keyPair) =>
|
||||
validateKeyPair(keyPair.key, keyPair.secret);
|
||||
|
||||
Future<bool> validateHash(Uint8List data, HashDigest hash);
|
||||
//Future<bool> validateHashReader(Stream<List<int>> reader, HashDigest hash);
|
||||
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2);
|
||||
Future<Signature> sign(PublicKey key, SecretKey secret, Uint8List data);
|
||||
Future<Signature> signWithKeyPair(KeyPair keyPair, Uint8List data) {
|
||||
return sign(keyPair.key, keyPair.secret, data);
|
||||
}
|
||||
Future<Signature> signWithKeyPair(KeyPair keyPair, Uint8List data) =>
|
||||
sign(keyPair.key, keyPair.secret, data);
|
||||
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature);
|
||||
Future<int> aeadOverhead();
|
||||
|
@ -27,22 +27,20 @@ class Uint8ListJsonConverter implements JsonConverter<Uint8List, String> {
|
||||
const Uint8ListJsonConverter();
|
||||
|
||||
@override
|
||||
Uint8List fromJson(String json) => base64UrlNoPadDecode(json);
|
||||
Uint8List fromJson(dynamic json) => base64UrlNoPadDecode(json as String);
|
||||
@override
|
||||
String toJson(Uint8List data) => base64UrlNoPadEncode(data);
|
||||
}
|
||||
|
||||
@immutable
|
||||
abstract class EncodedString extends Equatable {
|
||||
|
||||
const EncodedString(String s) : contents = s;
|
||||
final String contents;
|
||||
@override
|
||||
List<Object> get props => [contents];
|
||||
|
||||
const EncodedString(String s) : contents = s;
|
||||
|
||||
Uint8List decode() {
|
||||
return base64UrlNoPadDecode(contents);
|
||||
}
|
||||
Uint8List decode() => base64UrlNoPadDecode(contents);
|
||||
|
||||
@override
|
||||
String toString() => contents;
|
||||
@ -76,96 +74,82 @@ abstract class EncodedString extends Equatable {
|
||||
|
||||
@immutable
|
||||
class FixedEncodedString32 extends EncodedString {
|
||||
const FixedEncodedString32._(String s) : super(s);
|
||||
static int encodedLength() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int decodedLength() {
|
||||
return 24;
|
||||
}
|
||||
|
||||
factory FixedEncodedString32.fromBytes(Uint8List bytes) {
|
||||
if (bytes.length != decodedLength()) {
|
||||
throw Exception("length ${bytes.length} should be ${decodedLength()}");
|
||||
throw Exception('length ${bytes.length} should be ${decodedLength()}');
|
||||
}
|
||||
return FixedEncodedString32._(base64UrlNoPadEncode(bytes));
|
||||
}
|
||||
|
||||
factory FixedEncodedString32.fromString(String s) {
|
||||
var d = base64UrlNoPadDecode(s);
|
||||
final d = base64UrlNoPadDecode(s);
|
||||
if (d.length != decodedLength()) {
|
||||
throw Exception("length ${s.length} should be ${encodedLength()}");
|
||||
throw Exception('length ${s.length} should be ${encodedLength()}');
|
||||
}
|
||||
return FixedEncodedString32._(s);
|
||||
}
|
||||
|
||||
String toJson() => toString();
|
||||
factory FixedEncodedString32.fromJson(dynamic json) =>
|
||||
FixedEncodedString32.fromString(json as String);
|
||||
const FixedEncodedString32._(super.s);
|
||||
static int encodedLength() => 32;
|
||||
|
||||
static int decodedLength() => 24;
|
||||
|
||||
String toJson() => toString();
|
||||
}
|
||||
|
||||
@immutable
|
||||
class FixedEncodedString43 extends EncodedString {
|
||||
const FixedEncodedString43._(String s) : super(s);
|
||||
static int encodedLength() {
|
||||
return 43;
|
||||
}
|
||||
|
||||
static int decodedLength() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
factory FixedEncodedString43.fromBytes(Uint8List bytes) {
|
||||
if (bytes.length != decodedLength()) {
|
||||
throw Exception("length ${bytes.length} should be ${decodedLength()}");
|
||||
throw Exception('length ${bytes.length} should be ${decodedLength()}');
|
||||
}
|
||||
return FixedEncodedString43._(base64UrlNoPadEncode(bytes));
|
||||
}
|
||||
|
||||
factory FixedEncodedString43.fromString(String s) {
|
||||
var d = base64UrlNoPadDecode(s);
|
||||
final d = base64UrlNoPadDecode(s);
|
||||
if (d.length != decodedLength()) {
|
||||
throw Exception("length ${s.length} should be ${encodedLength()}");
|
||||
throw Exception('length ${s.length} should be ${encodedLength()}');
|
||||
}
|
||||
return FixedEncodedString43._(s);
|
||||
}
|
||||
|
||||
String toJson() => toString();
|
||||
factory FixedEncodedString43.fromJson(dynamic json) =>
|
||||
FixedEncodedString43.fromString(json as String);
|
||||
const FixedEncodedString43._(super.s);
|
||||
static int encodedLength() => 43;
|
||||
|
||||
static int decodedLength() => 32;
|
||||
|
||||
String toJson() => toString();
|
||||
}
|
||||
|
||||
@immutable
|
||||
class FixedEncodedString86 extends EncodedString {
|
||||
const FixedEncodedString86._(String s) : super(s);
|
||||
static int encodedLength() {
|
||||
return 86;
|
||||
}
|
||||
|
||||
static int decodedLength() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
String toJson() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
factory FixedEncodedString86.fromBytes(Uint8List bytes) {
|
||||
if (bytes.length != decodedLength()) {
|
||||
throw Exception("length ${bytes.length} should be ${decodedLength()}");
|
||||
throw Exception('length ${bytes.length} should be ${decodedLength()}');
|
||||
}
|
||||
return FixedEncodedString86._(base64UrlNoPadEncode(bytes));
|
||||
}
|
||||
|
||||
factory FixedEncodedString86.fromString(String s) {
|
||||
var d = base64UrlNoPadDecode(s);
|
||||
final d = base64UrlNoPadDecode(s);
|
||||
if (d.length != decodedLength()) {
|
||||
throw Exception("length ${s.length} should be ${encodedLength()}");
|
||||
throw Exception('length ${s.length} should be ${encodedLength()}');
|
||||
}
|
||||
return FixedEncodedString86._(s);
|
||||
}
|
||||
|
||||
factory FixedEncodedString86.fromJson(dynamic json) =>
|
||||
FixedEncodedString86.fromString(json as String);
|
||||
const FixedEncodedString86._(super.s);
|
||||
static int encodedLength() => 86;
|
||||
|
||||
static int decodedLength() => 64;
|
||||
|
||||
String toJson() => toString();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,52 +1,53 @@
|
||||
import 'veilid.dart';
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:html' as html;
|
||||
import 'dart:js' as js;
|
||||
import 'dart:js_util' as js_util;
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'veilid_encoding.dart';
|
||||
import 'veilid.dart';
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
Veilid getVeilid() => VeilidJS();
|
||||
|
||||
Object wasm = js_util.getProperty(html.window, "veilid_wasm");
|
||||
Object wasm = js_util.getProperty(html.window, 'veilid_wasm');
|
||||
|
||||
Future<T> _wrapApiPromise<T>(Object p) {
|
||||
return js_util.promiseToFuture(p).then((value) => value as T).catchError(
|
||||
(error) => Future<T>.error(
|
||||
VeilidAPIException.fromJson(jsonDecode(error as String))));
|
||||
}
|
||||
Future<T> _wrapApiPromise<T>(Object p) => js_util
|
||||
.promiseToFuture<T>(p)
|
||||
.then((value) => value)
|
||||
// ignore: inference_failure_on_untyped_parameter
|
||||
.catchError((e) {
|
||||
// Wrap all other errors in VeilidAPIExceptionInternal
|
||||
throw VeilidAPIExceptionInternal(e.toString());
|
||||
}, test: (e) => e is! VeilidAPIException);
|
||||
|
||||
class _Ctx {
|
||||
int? id;
|
||||
_Ctx(int id, this.js) : _id = id;
|
||||
int? _id;
|
||||
final VeilidJS js;
|
||||
_Ctx(int this.id, this.js);
|
||||
void ensureValid() {
|
||||
if (id == null) {
|
||||
int requireId() {
|
||||
if (_id == null) {
|
||||
throw VeilidAPIExceptionNotInitialized();
|
||||
}
|
||||
return _id!;
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (id != null) {
|
||||
js_util.callMethod(wasm, "release_routing_context", [id!]);
|
||||
id = null;
|
||||
if (_id != null) {
|
||||
js_util.callMethod<void>(wasm, 'release_routing_context', [_id]);
|
||||
_id = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JS implementation of VeilidRoutingContext
|
||||
class VeilidRoutingContextJS extends VeilidRoutingContext {
|
||||
final _Ctx _ctx;
|
||||
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
|
||||
|
||||
VeilidRoutingContextJS._(this._ctx) {
|
||||
_finalizer.attach(this, _ctx, detach: this);
|
||||
}
|
||||
final _Ctx _ctx;
|
||||
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
|
||||
|
||||
@override
|
||||
void close() {
|
||||
@ -55,113 +56,113 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
||||
|
||||
@override
|
||||
VeilidRoutingContextJS withPrivacy() {
|
||||
_ctx.ensureValid();
|
||||
int newId =
|
||||
js_util.callMethod(wasm, "routing_context_with_privacy", [_ctx.id!]);
|
||||
final id = _ctx.requireId();
|
||||
final int newId =
|
||||
js_util.callMethod(wasm, 'routing_context_with_privacy', [id]);
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextJS withCustomPrivacy(SafetySelection safetySelection) {
|
||||
_ctx.ensureValid();
|
||||
final newId = js_util.callMethod(
|
||||
final id = _ctx.requireId();
|
||||
final newId = js_util.callMethod<int>(
|
||||
wasm,
|
||||
"routing_context_with_custom_privacy",
|
||||
[_ctx.id!, jsonEncode(safetySelection)]);
|
||||
'routing_context_with_custom_privacy',
|
||||
[id, jsonEncode(safetySelection)]);
|
||||
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextJS withSequencing(Sequencing sequencing) {
|
||||
_ctx.ensureValid();
|
||||
final newId = js_util.callMethod(wasm, "routing_context_with_sequencing",
|
||||
[_ctx.id!, jsonEncode(sequencing)]);
|
||||
final id = _ctx.requireId();
|
||||
final newId = js_util.callMethod<int>(
|
||||
wasm, 'routing_context_with_sequencing', [id, jsonEncode(sequencing)]);
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> appCall(String target, Uint8List request) async {
|
||||
_ctx.ensureValid();
|
||||
var encodedRequest = base64UrlNoPadEncode(request);
|
||||
final id = _ctx.requireId();
|
||||
final encodedRequest = base64UrlNoPadEncode(request);
|
||||
|
||||
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_app_call", [_ctx.id!, target, encodedRequest])));
|
||||
wasm, 'routing_context_app_call', [id, target, encodedRequest])));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> appMessage(String target, Uint8List message) {
|
||||
_ctx.ensureValid();
|
||||
var encodedMessage = base64UrlNoPadEncode(message);
|
||||
final id = _ctx.requireId();
|
||||
final encodedMessage = base64UrlNoPadEncode(message);
|
||||
|
||||
return _wrapApiPromise(js_util.callMethod(wasm,
|
||||
"routing_context_app_message", [_ctx.id!, target, encodedMessage]));
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'routing_context_app_message', [id, target, encodedMessage]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DHTRecordDescriptor> createDHTRecord(DHTSchema schema,
|
||||
{CryptoKind kind = 0}) async {
|
||||
_ctx.ensureValid();
|
||||
final id = _ctx.requireId();
|
||||
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "routing_context_create_dht_record",
|
||||
[_ctx.id!, jsonEncode(schema), kind]))));
|
||||
.callMethod(wasm, 'routing_context_create_dht_record',
|
||||
[id, jsonEncode(schema), kind]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DHTRecordDescriptor> openDHTRecord(
|
||||
TypedKey key, KeyPair? writer) async {
|
||||
_ctx.ensureValid();
|
||||
final id = _ctx.requireId();
|
||||
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "routing_context_open_dht_record", [
|
||||
_ctx.id!,
|
||||
.callMethod(wasm, 'routing_context_open_dht_record', [
|
||||
id,
|
||||
jsonEncode(key),
|
||||
writer != null ? jsonEncode(writer) : null
|
||||
if (writer != null) jsonEncode(writer) else null
|
||||
]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> closeDHTRecord(TypedKey key) {
|
||||
_ctx.ensureValid();
|
||||
final id = _ctx.requireId();
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_close_dht_record", [_ctx.id!, jsonEncode(key)]));
|
||||
wasm, 'routing_context_close_dht_record', [id, jsonEncode(key)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteDHTRecord(TypedKey key) {
|
||||
_ctx.ensureValid();
|
||||
return _wrapApiPromise(js_util.callMethod(wasm,
|
||||
"routing_context_delete_dht_record", [_ctx.id!, jsonEncode(key)]));
|
||||
final id = _ctx.requireId();
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'routing_context_delete_dht_record', [id, jsonEncode(key)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ValueData?> getDHTValue(
|
||||
TypedKey key, int subkey, bool forceRefresh) async {
|
||||
_ctx.ensureValid();
|
||||
final opt = await _wrapApiPromise(js_util.callMethod(
|
||||
final id = _ctx.requireId();
|
||||
final opt = await _wrapApiPromise<String?>(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_get_dht_value",
|
||||
[_ctx.id!, jsonEncode(key), subkey, forceRefresh]));
|
||||
'routing_context_get_dht_value',
|
||||
[id, jsonEncode(key), subkey, forceRefresh]));
|
||||
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ValueData?> setDHTValue(
|
||||
TypedKey key, int subkey, Uint8List data) async {
|
||||
_ctx.ensureValid();
|
||||
final opt = await _wrapApiPromise(js_util.callMethod(
|
||||
final id = _ctx.requireId();
|
||||
final opt = await _wrapApiPromise<String?>(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_set_dht_value",
|
||||
[_ctx.id!, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
|
||||
'routing_context_set_dht_value',
|
||||
[id, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
|
||||
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
|
||||
Timestamp expiration, int count) async {
|
||||
_ctx.ensureValid();
|
||||
final ts = await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_watch_dht_values", [
|
||||
_ctx.id!,
|
||||
final id = _ctx.requireId();
|
||||
final ts = await _wrapApiPromise<String>(js_util.callMethod(
|
||||
wasm, 'routing_context_watch_dht_values', [
|
||||
id,
|
||||
jsonEncode(key),
|
||||
jsonEncode(subkeys),
|
||||
expiration.toString(),
|
||||
@ -172,195 +173,176 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
||||
|
||||
@override
|
||||
Future<bool> cancelDHTWatch(TypedKey key, List<ValueSubkeyRange> subkeys) {
|
||||
_ctx.ensureValid();
|
||||
final id = _ctx.requireId();
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_cancel_dht_watch",
|
||||
[_ctx.id!, jsonEncode(key), jsonEncode(subkeys)]));
|
||||
'routing_context_cancel_dht_watch',
|
||||
[id, jsonEncode(key), jsonEncode(subkeys)]));
|
||||
}
|
||||
}
|
||||
|
||||
// JS implementation of VeilidCryptoSystem
|
||||
class VeilidCryptoSystemJS extends VeilidCryptoSystem {
|
||||
VeilidCryptoSystemJS._(this._js, this._kind);
|
||||
|
||||
final CryptoKind _kind;
|
||||
// Keep the reference
|
||||
// ignore: unused_field
|
||||
final VeilidJS _js;
|
||||
|
||||
VeilidCryptoSystemJS._(this._js, this._kind) {
|
||||
// Keep the reference
|
||||
_js;
|
||||
}
|
||||
@override
|
||||
CryptoKind kind() => _kind;
|
||||
|
||||
@override
|
||||
CryptoKind kind() {
|
||||
return _kind;
|
||||
}
|
||||
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async =>
|
||||
SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
'crypto_cached_dh',
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
|
||||
@override
|
||||
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_cached_dh",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
}
|
||||
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async =>
|
||||
SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
'crypto_compute_dh',
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
|
||||
@override
|
||||
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_compute_dh",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
}
|
||||
Future<Uint8List> randomBytes(int len) async =>
|
||||
base64UrlNoPadDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_random_bytes', [_kind, len])));
|
||||
|
||||
@override
|
||||
Future<Uint8List> randomBytes(int len) async {
|
||||
return base64UrlNoPadDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_bytes", [_kind, len])));
|
||||
}
|
||||
Future<int> defaultSaltLength() => _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_default_salt_length', [_kind]));
|
||||
|
||||
@override
|
||||
Future<int> defaultSaltLength() {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_default_salt_length", [_kind]));
|
||||
}
|
||||
Future<String> hashPassword(Uint8List password, Uint8List salt) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_hash_password',
|
||||
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
|
||||
|
||||
@override
|
||||
Future<String> hashPassword(Uint8List password, Uint8List salt) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_hash_password",
|
||||
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> verifyPassword(Uint8List password, String passwordHash) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify_password",
|
||||
[_kind, base64UrlNoPadEncode(password), passwordHash]));
|
||||
}
|
||||
Future<bool> verifyPassword(Uint8List password, String passwordHash) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify_password',
|
||||
[_kind, base64UrlNoPadEncode(password), passwordHash]));
|
||||
|
||||
@override
|
||||
Future<SharedSecret> deriveSharedSecret(
|
||||
Uint8List password, Uint8List salt) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_derive_shared_secret", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(password),
|
||||
base64UrlNoPadEncode(salt)
|
||||
]))));
|
||||
}
|
||||
Uint8List password, Uint8List salt) async =>
|
||||
SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'crypto_derive_shared_secret', [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(password),
|
||||
base64UrlNoPadEncode(salt)
|
||||
]))));
|
||||
|
||||
@override
|
||||
Future<Nonce> randomNonce() async {
|
||||
return Nonce.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_nonce", [_kind]))));
|
||||
}
|
||||
Future<Nonce> randomNonce() async =>
|
||||
Nonce.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_random_nonce', [_kind]))));
|
||||
|
||||
@override
|
||||
Future<SharedSecret> randomSharedSecret() async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_shared_secret", [_kind]))));
|
||||
}
|
||||
Future<SharedSecret> randomSharedSecret() async =>
|
||||
SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_random_shared_secret', [_kind]))));
|
||||
|
||||
@override
|
||||
Future<KeyPair> generateKeyPair() async {
|
||||
return KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_generate_key_pair", [_kind]))));
|
||||
}
|
||||
Future<KeyPair> generateKeyPair() async =>
|
||||
KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_generate_key_pair', [_kind]))));
|
||||
|
||||
@override
|
||||
Future<HashDigest> generateHash(Uint8List data) async {
|
||||
return HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_generate_hash",
|
||||
[_kind, base64UrlNoPadEncode(data)]))));
|
||||
}
|
||||
Future<HashDigest> generateHash(Uint8List data) async =>
|
||||
HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'crypto_generate_hash', [_kind, base64UrlNoPadEncode(data)]))));
|
||||
|
||||
@override
|
||||
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_key_pair",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]));
|
||||
}
|
||||
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_key_pair',
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]));
|
||||
|
||||
@override
|
||||
Future<bool> validateHash(Uint8List data, HashDigest hash) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_hash",
|
||||
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
|
||||
}
|
||||
Future<bool> validateHash(Uint8List data, HashDigest hash) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_hash',
|
||||
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
|
||||
|
||||
@override
|
||||
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async {
|
||||
return CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_distance",
|
||||
[_kind, jsonEncode(key1), jsonEncode(key2)]))));
|
||||
}
|
||||
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async =>
|
||||
CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, 'crypto_distance',
|
||||
[_kind, jsonEncode(key1), jsonEncode(key2)]))));
|
||||
|
||||
@override
|
||||
Future<Signature> sign(
|
||||
PublicKey key, SecretKey secret, Uint8List data) async {
|
||||
return Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_sign", [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
jsonEncode(secret),
|
||||
base64UrlNoPadEncode(data)
|
||||
]))));
|
||||
}
|
||||
PublicKey key, SecretKey secret, Uint8List data) async =>
|
||||
Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'crypto_sign', [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
jsonEncode(secret),
|
||||
base64UrlNoPadEncode(data)
|
||||
]))));
|
||||
|
||||
@override
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify", [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signature),
|
||||
]));
|
||||
}
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signature),
|
||||
]));
|
||||
|
||||
@override
|
||||
Future<int> aeadOverhead() {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_aead_overhead", [_kind]));
|
||||
}
|
||||
Future<int> aeadOverhead() => _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_aead_overhead', [_kind]));
|
||||
|
||||
@override
|
||||
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async {
|
||||
return base64UrlNoPadDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_decrypt_aead", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
|
||||
])));
|
||||
}
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async =>
|
||||
base64UrlNoPadDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_decrypt_aead', [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
if (associatedData != null)
|
||||
base64UrlNoPadEncode(associatedData)
|
||||
else
|
||||
null
|
||||
])));
|
||||
|
||||
@override
|
||||
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async {
|
||||
return base64UrlNoPadDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_encrypt_aead", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
|
||||
])));
|
||||
}
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async =>
|
||||
base64UrlNoPadDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'crypto_encrypt_aead', [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
if (associatedData != null)
|
||||
base64UrlNoPadEncode(associatedData)
|
||||
else
|
||||
null
|
||||
])));
|
||||
|
||||
@override
|
||||
Future<Uint8List> cryptNoAuth(
|
||||
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async {
|
||||
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "crypto_crypt_no_auth", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret)
|
||||
])));
|
||||
}
|
||||
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async =>
|
||||
base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, 'crypto_crypt_no_auth', [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret)
|
||||
])));
|
||||
}
|
||||
|
||||
class _TDBT {
|
||||
_TDBT(this.id, this.tdbjs, this.js);
|
||||
int? id;
|
||||
final VeilidTableDBJS tdbjs;
|
||||
final VeilidJS js;
|
||||
|
||||
_TDBT(this.id, this.tdbjs, this.js);
|
||||
void ensureValid() {
|
||||
if (id == null) {
|
||||
throw VeilidAPIExceptionNotInitialized();
|
||||
@ -369,7 +351,7 @@ class _TDBT {
|
||||
|
||||
void close() {
|
||||
if (id != null) {
|
||||
js_util.callMethod(wasm, "release_table_db_transaction", [id!]);
|
||||
js_util.callMethod<void>(wasm, 'release_table_db_transaction', [id]);
|
||||
id = null;
|
||||
}
|
||||
}
|
||||
@ -377,81 +359,83 @@ class _TDBT {
|
||||
|
||||
// JS implementation of VeilidTableDBTransaction
|
||||
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
|
||||
final _TDBT _tdbt;
|
||||
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
|
||||
|
||||
VeilidTableDBTransactionJS._(this._tdbt) {
|
||||
_finalizer.attach(this, _tdbt, detach: this);
|
||||
}
|
||||
final _TDBT _tdbt;
|
||||
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
|
||||
|
||||
@override
|
||||
bool isDone() {
|
||||
return _tdbt.id == null;
|
||||
}
|
||||
bool isDone() => _tdbt.id == null;
|
||||
|
||||
@override
|
||||
Future<void> commit() async {
|
||||
_tdbt.ensureValid();
|
||||
await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "table_db_transaction_commit", [_tdbt.id!]));
|
||||
final id = _tdbt.id!;
|
||||
await _wrapApiPromise<void>(
|
||||
js_util.callMethod(wasm, 'table_db_transaction_commit', [id]));
|
||||
_tdbt.close();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rollback() async {
|
||||
_tdbt.ensureValid();
|
||||
await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "table_db_transaction_rollback", [_tdbt.id!]));
|
||||
final id = _tdbt.id!;
|
||||
await _wrapApiPromise<void>(
|
||||
js_util.callMethod(wasm, 'table_db_transaction_rollback', [id]));
|
||||
_tdbt.close();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> store(int col, Uint8List key, Uint8List value) async {
|
||||
_tdbt.ensureValid();
|
||||
final id = _tdbt.id!;
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
final encodedValue = base64UrlNoPadEncode(value);
|
||||
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "table_db_transaction_store",
|
||||
[_tdbt.id!, col, encodedKey, encodedValue]));
|
||||
await _wrapApiPromise<void>(js_util.callMethod(wasm,
|
||||
'table_db_transaction_store', [id, col, encodedKey, encodedValue]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> delete(int col, Uint8List key) async {
|
||||
_tdbt.ensureValid();
|
||||
final id = _tdbt.id!;
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
|
||||
await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "table_db_transaction_delete", [_tdbt.id!, col, encodedKey]));
|
||||
await _wrapApiPromise<void>(js_util.callMethod(
|
||||
wasm, 'table_db_transaction_delete', [id, col, encodedKey]));
|
||||
}
|
||||
}
|
||||
|
||||
class _TDB {
|
||||
int? id;
|
||||
final VeilidJS js;
|
||||
_TDB(int id, this.js) : _id = id;
|
||||
|
||||
_TDB(int this.id, this.js);
|
||||
void ensureValid() {
|
||||
if (id == null) {
|
||||
int? _id;
|
||||
|
||||
final VeilidJS js;
|
||||
int requireId() {
|
||||
if (_id == null) {
|
||||
throw VeilidAPIExceptionNotInitialized();
|
||||
}
|
||||
return _id!;
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (id != null) {
|
||||
js_util.callMethod(wasm, "release_table_db", [id!]);
|
||||
id = null;
|
||||
if (_id != null) {
|
||||
js_util.callMethod<void>(wasm, 'release_table_db', [_id]);
|
||||
_id = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JS implementation of VeilidTableDB
|
||||
class VeilidTableDBJS extends VeilidTableDB {
|
||||
final _TDB _tdb;
|
||||
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
|
||||
|
||||
VeilidTableDBJS._(this._tdb) {
|
||||
_finalizer.attach(this, _tdb, detach: this);
|
||||
}
|
||||
final _TDB _tdb;
|
||||
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
|
||||
|
||||
@override
|
||||
void close() {
|
||||
@ -460,42 +444,42 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
|
||||
@override
|
||||
int getColumnCount() {
|
||||
_tdb.ensureValid();
|
||||
return js_util.callMethod(wasm, "table_db_get_column_count", [_tdb.id!]);
|
||||
final id = _tdb.requireId();
|
||||
return js_util.callMethod(wasm, 'table_db_get_column_count', [id]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Uint8List>> getKeys(int col) async {
|
||||
_tdb.ensureValid();
|
||||
final id = _tdb.requireId();
|
||||
return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode(
|
||||
await js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id!, col])));
|
||||
await js_util.callMethod(wasm, 'table_db_get_keys', [id, col])));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidTableDBTransaction transact() {
|
||||
_tdb.ensureValid();
|
||||
final id = js_util.callMethod(wasm, "table_db_transact", [_tdb.id!]);
|
||||
final id = _tdb.requireId();
|
||||
final xid = js_util.callMethod<int>(wasm, 'table_db_transact', [id]);
|
||||
|
||||
return VeilidTableDBTransactionJS._(_TDBT(id, this, _tdb.js));
|
||||
return VeilidTableDBTransactionJS._(_TDBT(xid, this, _tdb.js));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> store(int col, Uint8List key, Uint8List value) {
|
||||
_tdb.ensureValid();
|
||||
final id = _tdb.requireId();
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
final encodedValue = base64UrlNoPadEncode(value);
|
||||
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "table_db_store", [_tdb.id!, col, encodedKey, encodedValue]));
|
||||
wasm, 'table_db_store', [id, col, encodedKey, encodedValue]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List?> load(int col, Uint8List key) async {
|
||||
_tdb.ensureValid();
|
||||
final id = _tdb.requireId();
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
|
||||
String? out = await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "table_db_load", [_tdb.id!, col, encodedKey]));
|
||||
final out = await _wrapApiPromise<String?>(
|
||||
js_util.callMethod(wasm, 'table_db_load', [id, col, encodedKey]));
|
||||
if (out == null) {
|
||||
return null;
|
||||
}
|
||||
@ -503,12 +487,16 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List?> delete(int col, Uint8List key) {
|
||||
_tdb.ensureValid();
|
||||
Future<Uint8List?> delete(int col, Uint8List key) async {
|
||||
final id = _tdb.requireId();
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
|
||||
return _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "table_db_delete", [_tdb.id!, col, encodedKey]));
|
||||
final out = await _wrapApiPromise<String?>(
|
||||
js_util.callMethod(wasm, 'table_db_delete', [id, col, encodedKey]));
|
||||
if (out == null) {
|
||||
return null;
|
||||
}
|
||||
return base64UrlNoPadDecode(out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,178 +505,164 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
class VeilidJS extends Veilid {
|
||||
@override
|
||||
void initializeVeilidCore(Map<String, dynamic> platformConfigJson) {
|
||||
var platformConfigJsonString = jsonEncode(platformConfigJson);
|
||||
js_util
|
||||
.callMethod(wasm, "initialize_veilid_core", [platformConfigJsonString]);
|
||||
final platformConfigJsonString = jsonEncode(platformConfigJson);
|
||||
js_util.callMethod<void>(
|
||||
wasm, 'initialize_veilid_core', [platformConfigJsonString]);
|
||||
}
|
||||
|
||||
@override
|
||||
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) {
|
||||
var logLevelJsonString = jsonEncode(logLevel);
|
||||
js_util.callMethod(wasm, "change_log_level", [layer, logLevelJsonString]);
|
||||
final logLevelJsonString = jsonEncode(logLevel);
|
||||
js_util.callMethod<void>(
|
||||
wasm, 'change_log_level', [layer, logLevelJsonString]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
|
||||
var streamController = StreamController<VeilidUpdate>();
|
||||
updateCallback(String update) {
|
||||
var updateJson = jsonDecode(update);
|
||||
if (updateJson["kind"] == "Shutdown") {
|
||||
streamController.close();
|
||||
final streamController = StreamController<VeilidUpdate>();
|
||||
void updateCallback(String update) {
|
||||
final updateJson = jsonDecode(update) as Map<String, dynamic>;
|
||||
if (updateJson['kind'] == 'Shutdown') {
|
||||
unawaited(streamController.close());
|
||||
} else {
|
||||
var update = VeilidUpdate.fromJson(updateJson);
|
||||
final update = VeilidUpdate.fromJson(updateJson);
|
||||
streamController.add(update);
|
||||
}
|
||||
}
|
||||
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "startup_veilid_core",
|
||||
await _wrapApiPromise<void>(js_util.callMethod(wasm, 'startup_veilid_core',
|
||||
[js.allowInterop(updateCallback), jsonEncode(config)]));
|
||||
|
||||
return streamController.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidState> getVeilidState() async {
|
||||
return VeilidState.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "get_veilid_state", []))));
|
||||
}
|
||||
Future<VeilidState> getVeilidState() async =>
|
||||
VeilidState.fromJson(jsonDecode(await _wrapApiPromise<String>(
|
||||
js_util.callMethod(wasm, 'get_veilid_state', []))));
|
||||
|
||||
@override
|
||||
Future<void> attach() {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "attach", []));
|
||||
}
|
||||
Future<void> attach() =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'attach', []));
|
||||
|
||||
@override
|
||||
Future<void> detach() {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "detach", []));
|
||||
}
|
||||
Future<void> detach() =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'detach', []));
|
||||
|
||||
@override
|
||||
Future<void> shutdownVeilidCore() {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "shutdown_veilid_core", []));
|
||||
}
|
||||
Future<void> shutdownVeilidCore() =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'shutdown_veilid_core', []));
|
||||
|
||||
@override
|
||||
List<CryptoKind> validCryptoKinds() {
|
||||
return jsonDecode(js_util.callMethod(wasm, "valid_crypto_kinds", []));
|
||||
final vck = jsonDecode(js_util.callMethod(wasm, 'valid_crypto_kinds', []))
|
||||
as List<dynamic>;
|
||||
return vck.map((v) => v as CryptoKind).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async {
|
||||
if (!validCryptoKinds().contains(kind)) {
|
||||
throw VeilidAPIExceptionGeneric("unsupported cryptosystem");
|
||||
throw const VeilidAPIExceptionGeneric('unsupported cryptosystem');
|
||||
}
|
||||
return VeilidCryptoSystemJS._(this, kind);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidCryptoSystem> bestCryptoSystem() async {
|
||||
return VeilidCryptoSystemJS._(
|
||||
this, js_util.callMethod(wasm, "best_crypto_kind", []));
|
||||
}
|
||||
Future<VeilidCryptoSystem> bestCryptoSystem() async => VeilidCryptoSystemJS._(
|
||||
this, js_util.callMethod(wasm, 'best_crypto_kind', []));
|
||||
|
||||
@override
|
||||
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
|
||||
Uint8List data, List<TypedSignature> signatures) async {
|
||||
return jsonListConstructor(TypedKey.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "verify_signatures", [
|
||||
jsonEncode(nodeIds),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signatures)
|
||||
]))));
|
||||
}
|
||||
Uint8List data, List<TypedSignature> signatures) async =>
|
||||
jsonListConstructor(TypedKey.fromJson)(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'verify_signatures', [
|
||||
jsonEncode(nodeIds),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signatures)
|
||||
]))));
|
||||
|
||||
@override
|
||||
Future<List<TypedSignature>> generateSignatures(
|
||||
Uint8List data, List<TypedKeyPair> keyPairs) async {
|
||||
return jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "generate_signatures",
|
||||
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
|
||||
}
|
||||
Uint8List data, List<TypedKeyPair> keyPairs) async =>
|
||||
jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, 'generate_signatures',
|
||||
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
|
||||
|
||||
@override
|
||||
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async {
|
||||
return TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "generate_key_pair", [kind]))));
|
||||
}
|
||||
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async =>
|
||||
TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'generate_key_pair', [kind]))));
|
||||
|
||||
@override
|
||||
Future<VeilidRoutingContext> routingContext() async {
|
||||
int id =
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "routing_context", []));
|
||||
return VeilidRoutingContextJS._(_Ctx(id, this));
|
||||
final rcid = await _wrapApiPromise<int>(
|
||||
js_util.callMethod(wasm, 'routing_context', []));
|
||||
return VeilidRoutingContextJS._(_Ctx(rcid, this));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<RouteBlob> newPrivateRoute() async {
|
||||
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "new_private_route", []))));
|
||||
}
|
||||
Future<RouteBlob> newPrivateRoute() async =>
|
||||
RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'new_private_route', []))));
|
||||
|
||||
@override
|
||||
Future<RouteBlob> newCustomPrivateRoute(
|
||||
Stability stability, Sequencing sequencing) async {
|
||||
var stabilityString = jsonEncode(stability);
|
||||
var sequencingString = jsonEncode(sequencing);
|
||||
final stabilityString = jsonEncode(stability);
|
||||
final sequencingString = jsonEncode(sequencing);
|
||||
|
||||
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(
|
||||
wasm, "new_private_route", [stabilityString, sequencingString]))));
|
||||
wasm, 'new_private_route', [stabilityString, sequencingString]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> importRemotePrivateRoute(Uint8List blob) {
|
||||
var encodedBlob = base64UrlNoPadEncode(blob);
|
||||
final encodedBlob = base64UrlNoPadEncode(blob);
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "import_remote_private_route", [encodedBlob]));
|
||||
js_util.callMethod(wasm, 'import_remote_private_route', [encodedBlob]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> releasePrivateRoute(String key) {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "release_private_route", [key]));
|
||||
}
|
||||
Future<void> releasePrivateRoute(String key) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'release_private_route', [key]));
|
||||
|
||||
@override
|
||||
Future<void> appCallReply(String callId, Uint8List message) {
|
||||
var encodedMessage = base64UrlNoPadEncode(message);
|
||||
final encodedMessage = base64UrlNoPadEncode(message);
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "app_call_reply", [callId, encodedMessage]));
|
||||
js_util.callMethod(wasm, 'app_call_reply', [callId, encodedMessage]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
|
||||
int id = await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "open_table_db", [name, columnCount]));
|
||||
return VeilidTableDBJS._(_TDB(id, this));
|
||||
final dbid = await _wrapApiPromise<int>(
|
||||
js_util.callMethod(wasm, 'open_table_db', [name, columnCount]));
|
||||
return VeilidTableDBJS._(_TDB(dbid, this));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> deleteTableDB(String name) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "delete_table_db", [name]));
|
||||
}
|
||||
Future<bool> deleteTableDB(String name) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'delete_table_db', [name]));
|
||||
|
||||
@override
|
||||
Timestamp now() {
|
||||
return Timestamp.fromString(js_util.callMethod(wasm, "now", []));
|
||||
}
|
||||
Timestamp now() => Timestamp.fromString(js_util.callMethod(wasm, 'now', []));
|
||||
|
||||
@override
|
||||
Future<String> debug(String command) async {
|
||||
return await _wrapApiPromise(js_util.callMethod(wasm, "debug", [command]));
|
||||
}
|
||||
Future<String> debug(String command) async =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'debug', [command]));
|
||||
|
||||
@override
|
||||
String veilidVersionString() {
|
||||
return js_util.callMethod(wasm, "veilid_version_string", []);
|
||||
}
|
||||
String veilidVersionString() =>
|
||||
js_util.callMethod(wasm, 'veilid_version_string', []);
|
||||
|
||||
@override
|
||||
VeilidVersion veilidVersion() {
|
||||
Map<String, dynamic> jsonVersion =
|
||||
jsonDecode(js_util.callMethod(wasm, "veilid_version", []));
|
||||
return VeilidVersion(
|
||||
jsonVersion["major"], jsonVersion["minor"], jsonVersion["patch"]);
|
||||
final jsonVersion =
|
||||
jsonDecode(js_util.callMethod(wasm, 'veilid_version', []))
|
||||
as Map<String, dynamic>;
|
||||
return VeilidVersion(jsonVersion['major'] as int,
|
||||
jsonVersion['minor'] as int, jsonVersion['patch'] as int);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class VeilidPluginStubWeb {
|
||||
Future<dynamic> handleMethodCall(MethodCall call) async {
|
||||
throw PlatformException(
|
||||
code: 'Unimplemented',
|
||||
details: 'Veilid for Web doesn\'t implement \'${call.method}\'',
|
||||
details: "Veilid for Web doesn't implement '${call.method}'",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,10 @@ enum AttachmentState {
|
||||
overAttached,
|
||||
detaching;
|
||||
|
||||
factory AttachmentState.fromJson(dynamic j) =>
|
||||
AttachmentState.values.byName((j as String).toCamelCase());
|
||||
|
||||
String toJson() => name.toPascalCase();
|
||||
factory AttachmentState.fromJson(String j) =>
|
||||
AttachmentState.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -36,9 +37,10 @@ enum VeilidLogLevel {
|
||||
debug,
|
||||
trace;
|
||||
|
||||
factory VeilidLogLevel.fromJson(dynamic j) =>
|
||||
VeilidLogLevel.values.byName((j as String).toCamelCase());
|
||||
|
||||
String toJson() => name.toPascalCase();
|
||||
factory VeilidLogLevel.fromJson(String j) =>
|
||||
VeilidLogLevel.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -51,8 +53,8 @@ class LatencyStats with _$LatencyStats {
|
||||
required TimestampDuration slowest,
|
||||
}) = _LatencyStats;
|
||||
|
||||
factory LatencyStats.fromJson(Map<String, dynamic> json) =>
|
||||
_$LatencyStatsFromJson(json);
|
||||
factory LatencyStats.fromJson(dynamic json) =>
|
||||
_$LatencyStatsFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -66,8 +68,8 @@ class TransferStats with _$TransferStats {
|
||||
required BigInt minimum,
|
||||
}) = _TransferStats;
|
||||
|
||||
factory TransferStats.fromJson(Map<String, dynamic> json) =>
|
||||
_$TransferStatsFromJson(json);
|
||||
factory TransferStats.fromJson(dynamic json) =>
|
||||
_$TransferStatsFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -79,8 +81,8 @@ class TransferStatsDownUp with _$TransferStatsDownUp {
|
||||
required TransferStats up,
|
||||
}) = _TransferStatsDownUp;
|
||||
|
||||
factory TransferStatsDownUp.fromJson(Map<String, dynamic> json) =>
|
||||
_$TransferStatsDownUpFromJson(json);
|
||||
factory TransferStatsDownUp.fromJson(dynamic json) =>
|
||||
_$TransferStatsDownUpFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -98,8 +100,8 @@ class RPCStats with _$RPCStats {
|
||||
required int failedToSend,
|
||||
}) = _RPCStats;
|
||||
|
||||
factory RPCStats.fromJson(Map<String, dynamic> json) =>
|
||||
_$RPCStatsFromJson(json);
|
||||
factory RPCStats.fromJson(dynamic json) =>
|
||||
_$RPCStatsFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -109,12 +111,12 @@ class PeerStats with _$PeerStats {
|
||||
const factory PeerStats({
|
||||
required Timestamp timeAdded,
|
||||
required RPCStats rpcStats,
|
||||
LatencyStats? latency,
|
||||
required TransferStatsDownUp transfer,
|
||||
LatencyStats? latency,
|
||||
}) = _PeerStats;
|
||||
|
||||
factory PeerStats.fromJson(Map<String, dynamic> json) =>
|
||||
_$PeerStatsFromJson(json);
|
||||
factory PeerStats.fromJson(dynamic json) =>
|
||||
_$PeerStatsFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
////////////
|
||||
@ -127,8 +129,8 @@ class PeerTableData with _$PeerTableData {
|
||||
required PeerStats peerStats,
|
||||
}) = _PeerTableData;
|
||||
|
||||
factory PeerTableData.fromJson(Map<String, dynamic> json) =>
|
||||
_$PeerTableDataFromJson(json);
|
||||
factory PeerTableData.fromJson(dynamic json) =>
|
||||
_$PeerTableDataFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -142,13 +144,13 @@ sealed class VeilidUpdate with _$VeilidUpdate {
|
||||
String? backtrace,
|
||||
}) = VeilidLog;
|
||||
const factory VeilidUpdate.appMessage({
|
||||
TypedKey? sender,
|
||||
@Uint8ListJsonConverter() required Uint8List message,
|
||||
TypedKey? sender,
|
||||
}) = VeilidAppMessage;
|
||||
const factory VeilidUpdate.appCall({
|
||||
TypedKey? sender,
|
||||
@Uint8ListJsonConverter() required Uint8List message,
|
||||
required String callId,
|
||||
TypedKey? sender,
|
||||
}) = VeilidAppCall;
|
||||
const factory VeilidUpdate.attachment(
|
||||
{required AttachmentState state,
|
||||
@ -173,8 +175,8 @@ sealed class VeilidUpdate with _$VeilidUpdate {
|
||||
required ValueData valueData,
|
||||
}) = VeilidUpdateValueChange;
|
||||
|
||||
factory VeilidUpdate.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidUpdateFromJson(json);
|
||||
factory VeilidUpdate.fromJson(dynamic json) =>
|
||||
_$VeilidUpdateFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -187,8 +189,8 @@ class VeilidStateAttachment with _$VeilidStateAttachment {
|
||||
required bool publicInternetReady,
|
||||
required bool localNetworkReady}) = _VeilidStateAttachment;
|
||||
|
||||
factory VeilidStateAttachment.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidStateAttachmentFromJson(json);
|
||||
factory VeilidStateAttachment.fromJson(dynamic json) =>
|
||||
_$VeilidStateAttachmentFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -202,8 +204,8 @@ class VeilidStateNetwork with _$VeilidStateNetwork {
|
||||
required BigInt bpsUp,
|
||||
required List<PeerTableData> peers}) = _VeilidStateNetwork;
|
||||
|
||||
factory VeilidStateNetwork.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidStateNetworkFromJson(json);
|
||||
factory VeilidStateNetwork.fromJson(dynamic json) =>
|
||||
_$VeilidStateNetworkFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -215,8 +217,8 @@ class VeilidStateConfig with _$VeilidStateConfig {
|
||||
required VeilidConfig config,
|
||||
}) = _VeilidStateConfig;
|
||||
|
||||
factory VeilidStateConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidStateConfigFromJson(json);
|
||||
factory VeilidStateConfig.fromJson(dynamic json) =>
|
||||
_$VeilidStateConfigFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -230,6 +232,6 @@ class VeilidState with _$VeilidState {
|
||||
required VeilidStateConfig config,
|
||||
}) = _VeilidState;
|
||||
|
||||
factory VeilidState.fromJson(Map<String, dynamic> json) =>
|
||||
_$VeilidStateFromJson(json);
|
||||
factory VeilidState.fromJson(dynamic json) =>
|
||||
_$VeilidStateFromJson(json as Map<String, dynamic>);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
/////////////////////////////////////
|
||||
/// VeilidTableDB
|
||||
@ -12,16 +12,14 @@ abstract class VeilidTableDBTransaction {
|
||||
Future<void> delete(int col, Uint8List key);
|
||||
|
||||
Future<void> storeJson(int col, Uint8List key, Object? object,
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) async {
|
||||
return store(col, key,
|
||||
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
|
||||
}
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) async =>
|
||||
store(col, key,
|
||||
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
|
||||
|
||||
Future<void> storeStringJson(int col, String key, Object? object,
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) {
|
||||
return storeJson(col, utf8.encoder.convert(key), object,
|
||||
toEncodable: toEncodable);
|
||||
}
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) =>
|
||||
storeJson(col, utf8.encoder.convert(key), object,
|
||||
toEncodable: toEncodable);
|
||||
}
|
||||
|
||||
abstract class VeilidTableDB {
|
||||
@ -34,20 +32,18 @@ abstract class VeilidTableDB {
|
||||
Future<Uint8List?> delete(int col, Uint8List key);
|
||||
|
||||
Future<void> storeJson(int col, Uint8List key, Object? object,
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) {
|
||||
return store(col, key,
|
||||
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
|
||||
}
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) =>
|
||||
store(col, key,
|
||||
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
|
||||
|
||||
Future<void> storeStringJson(int col, String key, Object? object,
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) {
|
||||
return storeJson(col, utf8.encoder.convert(key), object,
|
||||
toEncodable: toEncodable);
|
||||
}
|
||||
{Object? Function(Object? nonEncodable)? toEncodable}) =>
|
||||
storeJson(col, utf8.encoder.convert(key), object,
|
||||
toEncodable: toEncodable);
|
||||
|
||||
Future<Object?> loadJson(int col, Uint8List key,
|
||||
{Object? Function(Object? key, Object? value)? reviver}) async {
|
||||
var s = await load(col, key);
|
||||
final s = await load(col, key);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
@ -55,13 +51,12 @@ abstract class VeilidTableDB {
|
||||
}
|
||||
|
||||
Future<Object?> loadStringJson(int col, String key,
|
||||
{Object? Function(Object? key, Object? value)? reviver}) {
|
||||
return loadJson(col, utf8.encoder.convert(key), reviver: reviver);
|
||||
}
|
||||
{Object? Function(Object? key, Object? value)? reviver}) =>
|
||||
loadJson(col, utf8.encoder.convert(key), reviver: reviver);
|
||||
|
||||
Future<Object?> deleteJson(int col, Uint8List key,
|
||||
{Object? Function(Object? key, Object? value)? reviver}) async {
|
||||
var s = await delete(col, key);
|
||||
final s = await delete(col, key);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
@ -69,7 +64,6 @@ abstract class VeilidTableDB {
|
||||
}
|
||||
|
||||
Future<Object?> deleteStringJson(int col, String key,
|
||||
{Object? Function(Object? key, Object? value)? reviver}) {
|
||||
return deleteJson(col, utf8.encoder.convert(key), reviver: reviver);
|
||||
}
|
||||
{Object? Function(Object? key, Object? value)? reviver}) =>
|
||||
deleteJson(col, utf8.encoder.convert(key), reviver: reviver);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: veilid
|
||||
version: 0.1.4
|
||||
version: 0.1.7
|
||||
description: Veilid Framework
|
||||
homepage: https://veilid.com
|
||||
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
@ -8,27 +8,28 @@ environment:
|
||||
sdk: '>=3.0.0 <4.0.0'
|
||||
|
||||
dependencies:
|
||||
change_case: ^1.0.1
|
||||
charcode: ^1.3.1
|
||||
equatable: ^2.0.5
|
||||
ffi: ^2.0.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
ffi: ^2.0.0
|
||||
change_case: ^1.0.1
|
||||
path_provider: ^2.0.9
|
||||
path: ^1.8.0
|
||||
system_info2: ^3.0.2
|
||||
charcode: ^1.3.1
|
||||
freezed_annotation: ^2.2.0
|
||||
json_annotation: ^4.8.1
|
||||
equatable: ^2.0.5
|
||||
|
||||
path: ^1.8.0
|
||||
path_provider: ^2.0.9
|
||||
system_info2: ^3.0.2
|
||||
system_info_plus: ^0.0.5
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.4.6
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.1
|
||||
build_runner: ^2.4.6
|
||||
freezed: ^2.3.5
|
||||
json_serializable: ^6.7.1
|
||||
lint_hard: ^4.0.0
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-flutter"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
@ -367,9 +367,8 @@ pub extern "C" fn shutdown_veilid_core(port: i64) {
|
||||
});
|
||||
}
|
||||
|
||||
fn add_routing_context(routing_context: veilid_core::RoutingContext) -> u32 {
|
||||
fn add_routing_context(rc: &mut BTreeMap<u32, veilid_core::RoutingContext>, routing_context: veilid_core::RoutingContext) -> u32 {
|
||||
let mut next_id: u32 = 1;
|
||||
let mut rc = ROUTING_CONTEXTS.lock();
|
||||
while rc.contains_key(&next_id) {
|
||||
next_id += 1;
|
||||
}
|
||||
@ -382,7 +381,8 @@ pub extern "C" fn routing_context(port: i64) {
|
||||
DartIsolateWrapper::new(port).spawn_result(async move {
|
||||
let veilid_api = get_veilid_api().await?;
|
||||
let routing_context = veilid_api.routing_context();
|
||||
let new_id = add_routing_context(routing_context);
|
||||
let mut rc = ROUTING_CONTEXTS.lock();
|
||||
let new_id = add_routing_context(&mut *rc, routing_context);
|
||||
APIResult::Ok(new_id)
|
||||
});
|
||||
}
|
||||
@ -398,14 +398,14 @@ pub extern "C" fn release_routing_context(id: u32) -> i32 {
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn routing_context_with_privacy(id: u32) -> u32 {
|
||||
let rc = ROUTING_CONTEXTS.lock();
|
||||
let mut rc = ROUTING_CONTEXTS.lock();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let Ok(routing_context) = routing_context.clone().with_privacy() else {
|
||||
return 0;
|
||||
};
|
||||
let new_id = add_routing_context(routing_context);
|
||||
let new_id = add_routing_context(&mut rc, routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
@ -414,14 +414,14 @@ pub extern "C" fn routing_context_with_custom_privacy(id: u32, safety_selection:
|
||||
let safety_selection: veilid_core::SafetySelection =
|
||||
veilid_core::deserialize_opt_json(safety_selection.into_opt_string()).unwrap();
|
||||
|
||||
let rc = ROUTING_CONTEXTS.lock();
|
||||
let mut rc = ROUTING_CONTEXTS.lock();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let Ok(routing_context) = routing_context.clone().with_custom_privacy(safety_selection) else {
|
||||
return 0;
|
||||
};
|
||||
let new_id = add_routing_context(routing_context);
|
||||
let new_id = add_routing_context(&mut rc, routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
@ -430,12 +430,12 @@ pub extern "C" fn routing_context_with_sequencing(id: u32, sequencing: FfiStr) -
|
||||
let sequencing: veilid_core::Sequencing =
|
||||
veilid_core::deserialize_opt_json(sequencing.into_opt_string()).unwrap();
|
||||
|
||||
let rc = ROUTING_CONTEXTS.lock();
|
||||
let mut rc = ROUTING_CONTEXTS.lock();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let routing_context = routing_context.clone().with_sequencing(sequencing);
|
||||
let new_id = add_routing_context(routing_context);
|
||||
let new_id = add_routing_context(&mut rc, routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
@ -569,7 +569,7 @@ pub extern "C" fn routing_context_delete_dht_record(port: i64, id: u32, key: Ffi
|
||||
#[no_mangle]
|
||||
pub extern "C" fn routing_context_get_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, force_refresh: bool) {
|
||||
let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap();
|
||||
DartIsolateWrapper::new(port).spawn_result_opt_json(async move {
|
||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||
let routing_context = {
|
||||
let rc = ROUTING_CONTEXTS.lock();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
@ -594,7 +594,7 @@ pub extern "C" fn routing_context_set_dht_value(port: i64, id: u32, key: FfiStr,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
DartIsolateWrapper::new(port).spawn_result_opt_json(async move {
|
||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||
let routing_context = {
|
||||
let rc = ROUTING_CONTEXTS.lock();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
@ -1404,7 +1404,7 @@ pub extern "C" fn crypto_decrypt_aead(port: i64, kind: u32, body: FfiStr, nonce:
|
||||
|
||||
let associated_data: Option<Vec<u8>> = associated_data.into_opt_string().map(|s| data_encoding::BASE64URL_NOPAD.decode(s.as_bytes()).unwrap());
|
||||
|
||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||
DartIsolateWrapper::new(port).spawn_result(async move {
|
||||
let veilid_api = get_veilid_api().await?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_decrypt_aead", "kind", kind.to_string()))?;
|
||||
@ -1412,6 +1412,7 @@ pub extern "C" fn crypto_decrypt_aead(port: i64, kind: u32, body: FfiStr, nonce:
|
||||
Some(ad) => Some(ad.as_slice()),
|
||||
None => None
|
||||
})?;
|
||||
let out = data_encoding::BASE64URL_NOPAD.encode(&out);
|
||||
APIResult::Ok(out)
|
||||
});
|
||||
}
|
||||
@ -1436,7 +1437,7 @@ pub extern "C" fn crypto_encrypt_aead(port: i64, kind: u32, body: FfiStr, nonce:
|
||||
|
||||
let associated_data: Option<Vec<u8>> = associated_data.into_opt_string().map(|s| data_encoding::BASE64URL_NOPAD.decode(s.as_bytes()).unwrap());
|
||||
|
||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||
DartIsolateWrapper::new(port).spawn_result(async move {
|
||||
let veilid_api = get_veilid_api().await?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_encrypt_aead", "kind", kind.to_string()))?;
|
||||
@ -1444,6 +1445,7 @@ pub extern "C" fn crypto_encrypt_aead(port: i64, kind: u32, body: FfiStr, nonce:
|
||||
Some(ad) => Some(ad.as_slice()),
|
||||
None => None
|
||||
})?;
|
||||
let out = data_encoding::BASE64URL_NOPAD.encode(&out);
|
||||
APIResult::Ok(out)
|
||||
});
|
||||
}
|
||||
@ -1468,11 +1470,12 @@ pub extern "C" fn crypto_crypt_no_auth(port: i64, kind: u32, body: FfiStr, nonce
|
||||
let shared_secret: veilid_core::SharedSecret =
|
||||
veilid_core::deserialize_opt_json(shared_secret.into_opt_string()).unwrap();
|
||||
|
||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||
DartIsolateWrapper::new(port).spawn_result(async move {
|
||||
let veilid_api = get_veilid_api().await?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_crypt_no_auth", "kind", kind.to_string()))?;
|
||||
csv.crypt_in_place_no_auth(&mut body, &nonce, &shared_secret);
|
||||
let body = data_encoding::BASE64URL_NOPAD.encode(&body);
|
||||
APIResult::Ok(body)
|
||||
});
|
||||
}
|
||||
|
@ -52,17 +52,6 @@ impl DartIsolateWrapper {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn spawn_result_opt_json<F, T, E>(self, future: F)
|
||||
where
|
||||
F: Future<Output = Result<Option<T>, E>> + Send + 'static,
|
||||
T: Serialize + Debug,
|
||||
E: Serialize + Debug,
|
||||
{
|
||||
spawn(async move {
|
||||
self.result_opt_json(future.await);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn result<T: IntoDart + Debug, E: Serialize + Debug>(self, result: Result<T, E>) -> bool {
|
||||
match result {
|
||||
Ok(v) => self.ok(v),
|
||||
@ -78,16 +67,6 @@ impl DartIsolateWrapper {
|
||||
Err(e) => self.err_json(e),
|
||||
}
|
||||
}
|
||||
pub fn result_opt_json<T: Serialize + Debug, E: Serialize + Debug>(
|
||||
self,
|
||||
result: Result<Option<T>, E>,
|
||||
) -> bool {
|
||||
match result {
|
||||
Ok(Some(v)) => self.ok_json(v),
|
||||
Ok(None) => self.ok(()),
|
||||
Err(e) => self.err_json(e),
|
||||
}
|
||||
}
|
||||
pub fn ok<T: IntoDart>(self, value: T) -> bool {
|
||||
self.isolate
|
||||
.post(vec![MESSAGE_OK.into_dart(), value.into_dart()])
|
||||
|
@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
void main() {
|
||||
Veilid api = Veilid.instance;
|
||||
final api = Veilid.instance;
|
||||
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "veilid"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
description = ""
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
readme = "README.md"
|
||||
|
70
veilid-python/tests/api.py
Normal file
70
veilid-python/tests/api.py
Normal file
@ -0,0 +1,70 @@
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
from collections.abc import Callable
|
||||
from functools import cache
|
||||
|
||||
from veilid.json_api import _JsonVeilidAPI
|
||||
|
||||
import veilid
|
||||
|
||||
ERRNO_PATTERN = re.compile(r"errno (\d+)", re.IGNORECASE)
|
||||
|
||||
|
||||
class VeilidTestConnectionError(Exception):
|
||||
"""The test client could not connect to the veilid-server."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@cache
|
||||
def server_info() -> tuple[str, int]:
|
||||
"""Return the hostname and port of the test server."""
|
||||
VEILID_SERVER = os.getenv("VEILID_SERVER")
|
||||
if VEILID_SERVER is None:
|
||||
return "localhost", 5959
|
||||
|
||||
hostname, *rest = VEILID_SERVER.split(":")
|
||||
if rest:
|
||||
return hostname, int(rest[0])
|
||||
return hostname, 5959
|
||||
|
||||
|
||||
async def api_connector(callback: Callable) -> _JsonVeilidAPI:
|
||||
"""Return an API connection if possible.
|
||||
|
||||
If the connection fails due to an inability to connect to the
|
||||
server's socket, raise an easy-to-catch VeilidTestConnectionError.
|
||||
"""
|
||||
|
||||
hostname, port = server_info()
|
||||
try:
|
||||
return await veilid.json_api_connect(hostname, port, callback)
|
||||
except OSError as exc:
|
||||
# This is a little goofy. The underlying Python library handles
|
||||
# connection errors in 2 ways, depending on how many connections
|
||||
# it attempted to make:
|
||||
#
|
||||
# - If it only tried to connect to one IP address socket, the
|
||||
# library propagates the one single OSError it got.
|
||||
#
|
||||
# - If it tried to connect to multiple sockets, perhaps because
|
||||
# the hostname resolved to several addresses (e.g. "localhost"
|
||||
# => 127.0.0.1 and ::1), then the library raises one exception
|
||||
# with all the failure exception strings joined together.
|
||||
|
||||
# If errno is set, it's the first kind of exception. Check that
|
||||
# it's the code we expected.
|
||||
if exc.errno is not None:
|
||||
if exc.errno == errno.ECONNREFUSED:
|
||||
raise VeilidTestConnectionError
|
||||
raise
|
||||
|
||||
# If not, use a regular expression to find all the errno values
|
||||
# in the combined error string. Check that all of them have the
|
||||
# code we're looking for.
|
||||
errnos = ERRNO_PATTERN.findall(str(exc))
|
||||
if all(int(err) == errno.ECONNREFUSED for err in errnos):
|
||||
raise VeilidTestConnectionError
|
||||
|
||||
raise
|
@ -1,35 +1,30 @@
|
||||
import os
|
||||
from functools import cache
|
||||
"""Common test fixtures."""
|
||||
|
||||
from typing import AsyncGenerator
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
import veilid
|
||||
from veilid.json_api import _JsonVeilidAPI
|
||||
|
||||
import veilid
|
||||
|
||||
from .api import VeilidTestConnectionError, api_connector
|
||||
|
||||
pytest_plugins = ("pytest_asyncio",)
|
||||
|
||||
|
||||
@cache
|
||||
def server_info() -> tuple[str, int]:
|
||||
"""Return the hostname and port of the test server."""
|
||||
VEILID_SERVER = os.getenv("VEILID_SERVER")
|
||||
if VEILID_SERVER is None:
|
||||
return "localhost", 5959
|
||||
|
||||
hostname, *rest = VEILID_SERVER.split(":")
|
||||
if rest:
|
||||
return hostname, int(rest[0])
|
||||
return hostname, 5959
|
||||
|
||||
|
||||
async def simple_update_callback(update: veilid.VeilidUpdate):
|
||||
print(f"VeilidUpdate: {update}")
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def api_connection() -> AsyncGenerator[_JsonVeilidAPI, None]:
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(hostname, port, simple_update_callback)
|
||||
try:
|
||||
api = await api_connector(simple_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
|
@ -7,7 +7,9 @@ import json
|
||||
from . import *
|
||||
|
||||
##################################################################
|
||||
BOGUS_KEY = veilid.TypedKey.from_value(veilid.CryptoKind.CRYPTO_KIND_VLD0, veilid.PublicKey.from_bytes(b' '))
|
||||
BOGUS_KEY = veilid.TypedKey.from_value(
|
||||
veilid.CryptoKind.CRYPTO_KIND_VLD0, veilid.PublicKey.from_bytes(b' '))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_dht_value_unopened(api_connection: veilid.VeilidAPI):
|
||||
@ -24,6 +26,7 @@ async def test_open_dht_record_nonexistent_no_writer(api_connection: veilid.Veil
|
||||
with pytest.raises(veilid.VeilidAPIError):
|
||||
out = await rc.open_dht_record(BOGUS_KEY, None)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_close_dht_record_nonexistent(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
@ -31,13 +34,15 @@ async def test_close_dht_record_nonexistent(api_connection: veilid.VeilidAPI):
|
||||
with pytest.raises(veilid.VeilidAPIError):
|
||||
await rc.close_dht_record(BOGUS_KEY)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete_dht_record_nonexistent(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
async with rc:
|
||||
with pytest.raises(veilid.VeilidAPIError):
|
||||
await rc.delete_dht_record(BOGUS_KEY)
|
||||
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_delete_dht_record_simple(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
@ -46,6 +51,7 @@ async def test_create_delete_dht_record_simple(api_connection: veilid.VeilidAPI)
|
||||
await rc.close_dht_record(rec.key)
|
||||
await rc.delete_dht_record(rec.key)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_dht_value_nonexistent(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
@ -55,34 +61,34 @@ async def test_get_dht_value_nonexistent(api_connection: veilid.VeilidAPI):
|
||||
await rc.close_dht_record(rec.key)
|
||||
await rc.delete_dht_record(rec.key)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_set_get_dht_value(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
async with rc:
|
||||
rec = await rc.create_dht_record(veilid.DHTSchema.dflt(2))
|
||||
|
||||
|
||||
vd = await rc.set_dht_value(rec.key, 0, b"BLAH BLAH BLAH")
|
||||
assert vd != None
|
||||
|
||||
assert vd == None
|
||||
|
||||
vd2 = await rc.get_dht_value(rec.key, 0, False)
|
||||
assert vd2 != None
|
||||
|
||||
|
||||
vd3 = await rc.get_dht_value(rec.key, 0, True)
|
||||
assert vd3 != None
|
||||
|
||||
vd4 = await rc.get_dht_value(rec.key, 1, False)
|
||||
assert vd4 == None
|
||||
|
||||
print("vd: {}", vd.__dict__)
|
||||
print("vd2: {}", vd2.__dict__)
|
||||
print("vd3: {}", vd3.__dict__)
|
||||
|
||||
assert vd == vd2
|
||||
assert vd2 == vd3
|
||||
|
||||
await rc.close_dht_record(rec.key)
|
||||
await rc.delete_dht_record(rec.key)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
@ -104,10 +110,7 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
|
||||
# Test subkey writes
|
||||
vdtemp = await rc.set_dht_value(key, 1, va)
|
||||
assert vdtemp != None
|
||||
assert vdtemp.data == va
|
||||
assert vdtemp.seq == 0
|
||||
assert vdtemp.writer == owner
|
||||
assert vdtemp == None
|
||||
|
||||
vdtemp = await rc.get_dht_value(key, 1, False)
|
||||
assert vdtemp.data == va
|
||||
@ -118,8 +121,7 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
assert vdtemp == None
|
||||
|
||||
vdtemp = await rc.set_dht_value(key, 0, vb)
|
||||
assert vdtemp.data == vb
|
||||
assert vdtemp.seq == 0
|
||||
assert vdtemp == None
|
||||
|
||||
vdtemp = await rc.get_dht_value(key, 0, True)
|
||||
assert vdtemp.data == vb
|
||||
@ -129,17 +131,11 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
|
||||
# Equal value should not trigger sequence number update
|
||||
vdtemp = await rc.set_dht_value(key, 1, va)
|
||||
assert vdtemp != None
|
||||
assert vdtemp.data == va
|
||||
assert vdtemp.seq == 0
|
||||
assert vdtemp.writer == owner
|
||||
assert vdtemp == None
|
||||
|
||||
# Different value should trigger sequence number update
|
||||
vdtemp = await rc.set_dht_value(key, 1, vb)
|
||||
assert vdtemp != None
|
||||
assert vdtemp.data == vb
|
||||
assert vdtemp.seq == 1
|
||||
assert vdtemp.writer == owner
|
||||
assert vdtemp == None
|
||||
|
||||
# Now that we initialized some subkeys
|
||||
# and verified they stored correctly
|
||||
@ -166,11 +162,8 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
|
||||
# Verify subkey 1 can be set a second time and it updates because seq is newer
|
||||
vdtemp = await rc.set_dht_value(key, 1, vc)
|
||||
assert vdtemp != None
|
||||
assert vdtemp.data == vc
|
||||
assert vdtemp.seq == 2
|
||||
assert vdtemp.writer == owner
|
||||
|
||||
assert vdtemp == None
|
||||
|
||||
# Verify the network got the subkey update with a refresh check
|
||||
vdtemp = await rc.get_dht_value(key, 1, True)
|
||||
assert vdtemp != None
|
||||
@ -183,7 +176,7 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
|
||||
await rc.close_dht_record(key)
|
||||
await rc.delete_dht_record(key)
|
||||
|
||||
|
||||
rec = await rc.open_dht_record(key, other_keypair)
|
||||
assert rec != None
|
||||
assert rec.key == key
|
||||
@ -195,12 +188,11 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||
# Verify subkey 1 can NOT be set because we have the wrong writer
|
||||
with pytest.raises(veilid.VeilidAPIError):
|
||||
vdtemp = await rc.set_dht_value(key, 1, va)
|
||||
|
||||
|
||||
# Verify subkey 0 can NOT be set because we have the wrong writer
|
||||
with pytest.raises(veilid.VeilidAPIError):
|
||||
vdtemp = await rc.set_dht_value(key, 0, va)
|
||||
|
||||
|
||||
# Clean up
|
||||
await rc.close_dht_record(key)
|
||||
await rc.delete_dht_record(key)
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Routing context veilid tests
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
import os
|
||||
|
||||
import pytest
|
||||
import veilid
|
||||
from veilid.types import OperationId
|
||||
|
||||
from .conftest import server_info
|
||||
import veilid
|
||||
|
||||
from .api import VeilidTestConnectionError, api_connector
|
||||
|
||||
##################################################################
|
||||
|
||||
@ -26,18 +26,24 @@ async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
||||
async with rcp:
|
||||
pass
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
rc = await (await api_connection.new_routing_context()).with_sequencing(
|
||||
veilid.Sequencing.ENSURE_ORDERED
|
||||
)
|
||||
async with rc:
|
||||
pass
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
||||
veilid.SafetySelection.safe(
|
||||
veilid.SafetySpec(None, 2, veilid.Stability.RELIABLE,
|
||||
veilid.Sequencing.ENSURE_ORDERED)
|
||||
))
|
||||
veilid.SafetySpec(
|
||||
None, 2, veilid.Stability.RELIABLE, veilid.Sequencing.ENSURE_ORDERED
|
||||
)
|
||||
)
|
||||
)
|
||||
await rc.release()
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(veilid.SafetySelection.unsafe(veilid.Sequencing.ENSURE_ORDERED))
|
||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
||||
veilid.SafetySelection.unsafe(veilid.Sequencing.ENSURE_ORDERED)
|
||||
)
|
||||
await rc.release()
|
||||
|
||||
|
||||
@ -50,10 +56,12 @@ async def test_routing_context_app_message_loopback():
|
||||
if update.kind == veilid.VeilidUpdateKind.APP_MESSAGE:
|
||||
await app_message_queue.put(update)
|
||||
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(
|
||||
hostname, port, app_message_queue_update_callback
|
||||
)
|
||||
try:
|
||||
api = await api_connector(app_message_queue_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
@ -61,7 +69,6 @@ async def test_routing_context_app_message_loopback():
|
||||
# make a routing context that uses a safety route
|
||||
rc = await (await api.new_routing_context()).with_privacy()
|
||||
async with rc:
|
||||
|
||||
# make a new local private route
|
||||
prl, blob = await api.new_private_route()
|
||||
|
||||
@ -89,8 +96,12 @@ async def test_routing_context_app_call_loopback():
|
||||
if update.kind == veilid.VeilidUpdateKind.APP_CALL:
|
||||
await app_call_queue.put(update)
|
||||
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(hostname, port, app_call_queue_update_callback)
|
||||
try:
|
||||
api = await api_connector(app_call_queue_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
@ -98,7 +109,6 @@ async def test_routing_context_app_call_loopback():
|
||||
# make a routing context that uses a safety route
|
||||
rc = await (await api.new_routing_context()).with_privacy()
|
||||
async with rc:
|
||||
|
||||
# make a new local private route
|
||||
prl, blob = await api.new_private_route()
|
||||
|
||||
@ -131,33 +141,33 @@ async def test_routing_context_app_call_loopback():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_routing_context_app_message_loopback_big_packets():
|
||||
|
||||
app_message_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
global got_message
|
||||
got_message = 0
|
||||
count_hack = [0]
|
||||
|
||||
async def app_message_queue_update_callback(update: veilid.VeilidUpdate):
|
||||
if update.kind == veilid.VeilidUpdateKind.APP_MESSAGE:
|
||||
global got_message
|
||||
got_message += 1
|
||||
sys.stdout.write("{} ".format(got_message))
|
||||
count_hack[0] += 1
|
||||
print(f"{count_hack[0]} ", end="")
|
||||
await app_message_queue.put(update)
|
||||
|
||||
sent_messages: set[bytes] = set()
|
||||
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(
|
||||
hostname, port, app_message_queue_update_callback
|
||||
)
|
||||
try:
|
||||
api = await api_connector(app_message_queue_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
|
||||
# make a routing context that uses a safety route
|
||||
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
rc = await (
|
||||
await (await api.new_routing_context()).with_privacy()
|
||||
).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
async with rc:
|
||||
|
||||
# make a new local private route
|
||||
prl, blob = await api.new_private_route()
|
||||
|
||||
@ -166,7 +176,6 @@ async def test_routing_context_app_message_loopback_big_packets():
|
||||
|
||||
# do this test 1000 times
|
||||
for _ in range(1000):
|
||||
|
||||
# send a random sized random app message to our own private route
|
||||
message = random.randbytes(random.randint(0, 32768))
|
||||
await rc.app_message(prr, message)
|
||||
@ -187,8 +196,7 @@ async def test_routing_context_app_message_loopback_big_packets():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_routing_context_app_call_loopback_big_packets():
|
||||
global got_message
|
||||
got_message = 0
|
||||
count_hack = [0]
|
||||
|
||||
app_call_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
@ -200,18 +208,17 @@ async def test_routing_context_app_call_loopback_big_packets():
|
||||
while True:
|
||||
update = await app_call_queue.get()
|
||||
|
||||
global got_message
|
||||
got_message += 1
|
||||
|
||||
sys.stdout.write("{} ".format(got_message))
|
||||
sys.stdout.flush()
|
||||
count_hack[0] += 1
|
||||
print(f"{count_hack[0]} ", end="", flush=True)
|
||||
|
||||
await api.app_call_reply(update.detail.call_id, update.detail.message)
|
||||
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(
|
||||
hostname, port, app_call_queue_update_callback
|
||||
)
|
||||
try:
|
||||
api = await api_connector(app_call_queue_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
@ -221,9 +228,10 @@ async def test_routing_context_app_call_loopback_big_packets():
|
||||
)
|
||||
|
||||
# make a routing context that uses a safety route
|
||||
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
rc = await (
|
||||
await (await api.new_routing_context()).with_privacy()
|
||||
).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
async with rc:
|
||||
|
||||
# make a new local private route
|
||||
prl, blob = await api.new_private_route()
|
||||
|
||||
@ -232,7 +240,6 @@ async def test_routing_context_app_call_loopback_big_packets():
|
||||
|
||||
# do this test 10 times
|
||||
for _ in range(10):
|
||||
|
||||
# send a random sized random app message to our own private route
|
||||
message = random.randbytes(random.randint(0, 32768))
|
||||
out_message = await rc.app_call(prr, message)
|
||||
@ -242,20 +249,23 @@ async def test_routing_context_app_call_loopback_big_packets():
|
||||
app_call_task.cancel()
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.getenv("NOSKIP") != "1", reason="unneeded test, only for performance check")
|
||||
@pytest.mark.skipif(
|
||||
os.getenv("NOSKIP") != "1", reason="unneeded test, only for performance check"
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_routing_context_app_message_loopback_bandwidth():
|
||||
|
||||
app_message_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
async def app_message_queue_update_callback(update: veilid.VeilidUpdate):
|
||||
if update.kind == veilid.VeilidUpdateKind.APP_MESSAGE:
|
||||
await app_message_queue.put(True)
|
||||
|
||||
hostname, port = server_info()
|
||||
api = await veilid.json_api_connect(
|
||||
hostname, port, app_message_queue_update_callback
|
||||
)
|
||||
try:
|
||||
api = await api_connector(app_message_queue_update_callback)
|
||||
except VeilidTestConnectionError:
|
||||
pytest.skip("Unable to connect to veilid-server.")
|
||||
return
|
||||
|
||||
async with api:
|
||||
# purge routes to ensure we start fresh
|
||||
await api.debug("purge routes")
|
||||
@ -265,7 +275,6 @@ async def test_routing_context_app_message_loopback_bandwidth():
|
||||
# rc = await (await api.new_routing_context()).with_privacy()
|
||||
rc = await api.new_routing_context()
|
||||
async with rc:
|
||||
|
||||
# make a new local private route
|
||||
prl, blob = await api.new_private_route()
|
||||
|
||||
@ -275,12 +284,9 @@ async def test_routing_context_app_message_loopback_bandwidth():
|
||||
# do this test 1000 times
|
||||
message = random.randbytes(16384)
|
||||
for _ in range(10000):
|
||||
|
||||
# send a random sized random app message to our own private route
|
||||
await rc.app_message(prr, message)
|
||||
|
||||
# we should get the same number of messages back (not storing all that data)
|
||||
for _ in range(10000):
|
||||
await asyncio.wait_for(
|
||||
app_message_queue.get(), timeout=10
|
||||
)
|
||||
await asyncio.wait_for(app_message_queue.get(), timeout=10)
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-server"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-tools"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
@ -12,7 +12,7 @@ const MAX_LEN: usize = LengthType::MAX as usize;
|
||||
|
||||
// XXX: keep statistics on all drops and why we dropped them
|
||||
// XXX: move to config eventually?
|
||||
const FRAGMENT_LEN: usize = 1280 - HEADER_LEN;
|
||||
pub const FRAGMENT_LEN: usize = 1280 - HEADER_LEN;
|
||||
const MAX_CONCURRENT_HOSTS: usize = 256;
|
||||
const MAX_ASSEMBLIES_PER_HOST: usize = 256;
|
||||
const MAX_BUFFER_PER_HOST: usize = 256 * 1024;
|
||||
|
@ -86,7 +86,7 @@ pub async fn test_one_frag_out_in() {
|
||||
// Sending
|
||||
println!("sending");
|
||||
for _ in 0..10000 {
|
||||
let random_len = (get_random_u32() % 1000) as usize + 1280;
|
||||
let random_len = (get_random_u32() % 1000) as usize + FRAGMENT_LEN;
|
||||
let mut message = vec![1u8; random_len];
|
||||
random_bytes(&mut message);
|
||||
let remote_addr = random_sockaddr();
|
||||
@ -289,7 +289,7 @@ pub async fn test_many_frags_with_drops() {
|
||||
println!("sending");
|
||||
for _ in 0..1000 {
|
||||
let random_len = (get_random_u32() % 65536) as usize;
|
||||
if random_len > 1280 {
|
||||
if random_len > FRAGMENT_LEN {
|
||||
total_fragged += 1;
|
||||
}
|
||||
total_sent_size += random_len;
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veilid-wasm"
|
||||
version = "0.1.4"
|
||||
version = "0.1.7"
|
||||
authors = ["Veilid Team <contact@veilid.com>"]
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
@ -60,12 +60,6 @@ fn take_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidAPIErr
|
||||
pub fn to_json<T: Serialize + Debug>(val: T) -> JsValue {
|
||||
JsValue::from_str(&serialize_json(val))
|
||||
}
|
||||
pub fn to_opt_json<T: Serialize + Debug>(val: Option<T>) -> JsValue {
|
||||
match val {
|
||||
Some(v) => JsValue::from_str(&serialize_json(v)),
|
||||
None => JsValue::UNDEFINED,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_jsvalue<T>(val: T) -> JsValue
|
||||
where
|
||||
@ -120,14 +114,6 @@ where
|
||||
future_to_promise(future.map(|res| res.map(|v| to_json(v)).map_err(|e| to_json(e))))
|
||||
}
|
||||
|
||||
pub fn wrap_api_future_opt_json<F, T>(future: F) -> Promise
|
||||
where
|
||||
F: Future<Output = APIResult<Option<T>>> + 'static,
|
||||
T: Serialize + Debug + 'static,
|
||||
{
|
||||
future_to_promise(future.map(|res| res.map(|v| to_opt_json(v)).map_err(|e| to_json(e))))
|
||||
}
|
||||
|
||||
pub fn wrap_api_future_plain<F, T>(future: F) -> Promise
|
||||
where
|
||||
F: Future<Output = APIResult<T>> + 'static,
|
||||
@ -507,7 +493,7 @@ pub fn routing_context_get_dht_value(
|
||||
force_refresh: bool,
|
||||
) -> Promise {
|
||||
let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap();
|
||||
wrap_api_future_opt_json(async move {
|
||||
wrap_api_future_json(async move {
|
||||
let routing_context = {
|
||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
@ -529,7 +515,7 @@ pub fn routing_context_set_dht_value(id: u32, key: String, subkey: u32, data: St
|
||||
.decode(&data.as_bytes())
|
||||
.unwrap();
|
||||
|
||||
wrap_api_future_opt_json(async move {
|
||||
wrap_api_future_json(async move {
|
||||
let routing_context = {
|
||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
@ -1361,7 +1347,7 @@ pub fn crypto_decrypt_aead(
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
wrap_api_future_json(async move {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| {
|
||||
@ -1380,6 +1366,7 @@ pub fn crypto_decrypt_aead(
|
||||
None => None,
|
||||
},
|
||||
)?;
|
||||
let out = data_encoding::BASE64URL_NOPAD.encode(&out);
|
||||
APIResult::Ok(out)
|
||||
})
|
||||
}
|
||||
@ -1409,7 +1396,7 @@ pub fn crypto_encrypt_aead(
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
wrap_api_future_json(async move {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| {
|
||||
@ -1428,6 +1415,7 @@ pub fn crypto_encrypt_aead(
|
||||
None => None,
|
||||
},
|
||||
)?;
|
||||
let out = data_encoding::BASE64URL_NOPAD.encode(&out);
|
||||
APIResult::Ok(out)
|
||||
})
|
||||
}
|
||||
@ -1450,7 +1438,7 @@ pub fn crypto_crypt_no_auth(
|
||||
let shared_secret: veilid_core::SharedSecret =
|
||||
veilid_core::deserialize_json(&shared_secret).unwrap();
|
||||
|
||||
wrap_api_future_json(async move {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let crypto = veilid_api.crypto()?;
|
||||
let csv = crypto.get(kind).ok_or_else(|| {
|
||||
@ -1461,6 +1449,7 @@ pub fn crypto_crypt_no_auth(
|
||||
)
|
||||
})?;
|
||||
csv.crypt_in_place_no_auth(&mut body, &nonce, &shared_secret);
|
||||
let out = data_encoding::BASE64URL_NOPAD.encode(&out);
|
||||
APIResult::Ok(body)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user