πΊοΈ Architecture details
This page presents the project architecture and some technical details.
ποΈ Changelog
Version history is recorded in the CHANGELOG.md.
ποΈ Folder structure
nanopub-rs/
βββ lib/
β βββ src/
β β βββ π¦ Source code for the core Rust crate.
β βββ tests/
β β βββ π§ͺ Tests for the core Rust crate.
β βββ docs/
β βββ π Markdown and HTML files for the documentation website.
βββ python/
β βββ π Python bindings for interacting with the Rust crate.
βββ js/
β βββ π JavaScript bindings for integrating into JS environments.
βββ cli/
β βββ β¨οΈ Scripts for the command-line interface.
βββ scripts/
β βββ π οΈ Development scripts (build docs, testing).
βββ .github/
βββ workflows/
βββ βοΈ Automated CI/CD workflows.
βοΈ Nanopub signing process
- Preliminary nanopub is created with blank space in URIs at the places where the trusty URI code will appear (normalized URI:
https://w3id.org/np/
, cf. original java implementation); this includes the signature part, except the triple that is stating the actual signature - Preliminary nanopub is serialized in a normalized fashion (basically each quad on four lines with minimal escaping)
- Signature is calculated on this normalized representation (cf. most of the process in the trusty-uri python lib, see also SignatureUtils and trusty-uri)
- Signature triple is added
- Trusty URI code is calculated on normalized representation that includes signature
- Trusty URI code is added in place of all the occurrences of blank spaces in the URIs, leading to the final trusty nanopub
π οΈ Notes about maintenance and stability
Cross-compiling to many targets brings some complexity to the build process, especially that the nanopub lib packs a lot of features: processing RDF, RSA signing and random key generation, querying a HTTP server, getting current datetime.
This means we need to make sure the dependencies we use work for all compilation targets (e.g. aarch64, wasm). And in some case we need to define platform dependant dependencies in the Cargo.toml
(e.g. reqwest native-tls
for aarch64 windows instead of the rustls-tls
)
Packages are built for different targets in the .github/workflows/build.yml
GitHub action.
βοΈ To do
- Add possibility to build the nanopub from scratch for JS and python
- Integrate to the python
nanopub
library to perform signing? - Add Ruby bindings? https://docs.rs/magnus/latest/magnus https://github.com/ankane/tokenizers-ruby
- Add Java bindings? https://docs.rs/jni/latest/jni
- Add brew packaging? (cf. ripgrep)
β±οΈ Speed comparison
Speed taken when signing a nanopub using different languages implementations (in this order: java, python, rust):
Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
---|---|---|---|---|
java -jar nanopub.jar sign lib/tests/resources/simple1-rsa.trig -k lib/tests/resources/id_rsa |
319.5 Β± 11.2 | 296.0 | 337.5 | 60.74 Β± 2.49 |
np sign lib/tests/resources/simple1-rsa.trig -k lib/tests/resources/id_rsa |
446.6 Β± 3.2 | 441.2 | 457.6 | 84.93 Β± 1.93 |
target/release/nanopub-cli sign lib/tests/resources/simple1-rsa.trig -k lib/tests/resources/id_rsa |
5.3 Β± 0.1 | 5.1 | 6.3 | 1.00 |
Tested in GitHub actions on Ubuntu.