mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 03:59:37 +00:00
Compare commits
85 commits
b538272f4d
...
7bac741d5f
Author | SHA1 | Date | |
---|---|---|---|
|
7bac741d5f | ||
|
39fe790553 | ||
|
a003e0588d | ||
521bf877db | |||
6da9d2d734 | |||
|
12bbadd749 | ||
a072d44a0d | |||
|
88605b081f | ||
|
5eb712f4de | ||
|
848a6a71c4 | ||
|
f4c88b6f05 | ||
|
c840053854 | ||
|
57af45e01d | ||
|
5588671501 | ||
|
19150df355 | ||
|
e7c6bba63d | ||
4169c45c58 | |||
|
e3a918bca5 | ||
|
a1267619ef | ||
|
2afc0e8373 | ||
|
b9842fcb18 | ||
|
8b4b403c5c | ||
|
6502729d8c | ||
|
2291a96795 | ||
90027143f0 | |||
49d1344aa1 | |||
|
967537fae1 | ||
|
01625535fa | ||
|
92800810d9 | ||
|
4653ac5884 | ||
|
0941f68efc | ||
|
eead49beb0 | ||
|
b837d350a4 | ||
|
bec8cc0aa4 | ||
fdd1689665 | |||
8655a3f5e5 | |||
|
ccff75057e | ||
7207fbd17b | |||
|
5648bf0da0 | ||
|
aeb070ae8d | ||
|
59adf6dcf8 | ||
|
bca062d2f5 | ||
|
ca3b149b39 | ||
0041650fd1 | |||
be2f3f2672 | |||
|
fafa20c20f | ||
|
eb65efa7fb | ||
8227c28604 | |||
|
27767690ca | ||
1a178381dd | |||
|
bd375eae40 | ||
|
dced4ed7ec | ||
86d1f408d8 | |||
b44c6b045b | |||
|
a2bca1b889 | ||
|
7416164b19 | ||
|
929d19c450 | ||
|
aa718e224f | ||
|
0a88ea13fc | ||
88551c800c | |||
|
6820da9848 | ||
|
0910c0a231 | ||
|
0a390a362a | ||
|
fbae3df203 | ||
|
824651c8cf | ||
|
5aeb8af4b4 | ||
|
612938eae6 | ||
|
303c165df7 | ||
|
ecbb5ad3dc | ||
|
5c3258a6e3 | ||
|
0d7b86abe3 | ||
|
03815efe29 | ||
|
136abf7edd | ||
a82c08cc80 | |||
d5c8eba1d8 | |||
|
71131a4836 | ||
|
a8b58fa4db | ||
7c8466f4ba | |||
|
6ce177aeca | ||
fb1f071faf | |||
f91be58a7f | |||
|
7e9891de5b | ||
|
a438279aa8 | ||
|
e405786a73 | ||
5c08d1a0e2 |
498 changed files with 27133 additions and 9010 deletions
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
|
@ -56,6 +56,10 @@ A-cryptonight:
|
|||
- changed-files:
|
||||
- any-glob-to-any-file: cryptonight/**
|
||||
|
||||
A-constants:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: constants/**
|
||||
|
||||
A-storage:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: storage/**
|
||||
|
|
40
.github/workflows/architecture-book.yml
vendored
Normal file
40
.github/workflows/architecture-book.yml
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
# This action attempts to build the architecture book, if changed.
|
||||
|
||||
name: Architecture mdBook
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
paths: ['books/architecture/**']
|
||||
pull_request:
|
||||
paths: ['books/architecture/**']
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Version of `mdbook` to install.
|
||||
MDBOOK_VERSION: 0.4.36
|
||||
# Version of `mdbook-last-changed` to install.
|
||||
# <https://github.com/badboy/mdbook-last-changed>.
|
||||
MDBOOK_LAST_CHANGED_VERSION: 0.1.4
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/mdbook
|
||||
~/.cargo/bin/mdbook-last-changed
|
||||
key: architecture-book
|
||||
|
||||
- name: Install mdBook
|
||||
run: |
|
||||
cargo install --locked --version ${MDBOOK_VERSION} mdbook || echo "mdbook already exists"
|
||||
cargo install --locked --version ${MDBOOK_LAST_CHANGED_VERSION} mdbook-last-changed || echo "mdbook-last-changed already exists"
|
||||
|
||||
- name: Build
|
||||
run: mdbook build books/architecture
|
1
.github/workflows/audit.yml
vendored
1
.github/workflows/audit.yml
vendored
|
@ -7,6 +7,7 @@ on:
|
|||
paths:
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
|
1
.github/workflows/deny.yml
vendored
1
.github/workflows/deny.yml
vendored
|
@ -7,6 +7,7 @@ on:
|
|||
paths:
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
|
74
.github/workflows/doc.yml
vendored
Normal file
74
.github/workflows/doc.yml
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
# This builds `cargo doc` and uploads it to the repo's GitHub Pages.
|
||||
|
||||
name: Doc
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ] # Only deploy if `main` changes.
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Show colored output in CI.
|
||||
CARGO_TERM_COLOR: always
|
||||
# Generate an index page.
|
||||
RUSTDOCFLAGS: '--cfg docsrs --show-type-layout --enable-index-page -Zunstable-options'
|
||||
|
||||
jobs:
|
||||
# Build documentation.
|
||||
build:
|
||||
# FIXME: how to build and merge Windows + macOS docs
|
||||
# with Linux's? Similar to the OS toggle on docs.rs.
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
# Nightly required for some `cargo doc` settings.
|
||||
toolchain: nightly
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
# Don't cache actual doc files, just build files.
|
||||
# This is so that removed crates don't show up.
|
||||
path: target/debug
|
||||
key: doc
|
||||
|
||||
# Packages other than `Boost` used by `Monero` are listed here.
|
||||
# https://github.com/monero-project/monero/blob/c444a7e002036e834bfb4c68f04a121ce1af5825/.github/workflows/build.yml#L71
|
||||
|
||||
- name: Install dependencies (Linux)
|
||||
run: sudo apt install -y libboost-dev
|
||||
|
||||
- name: Documentation
|
||||
run: cargo +nightly doc --workspace --all-features
|
||||
|
||||
- name: Upload documentation
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: target/doc/
|
||||
|
||||
# Deployment job.
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
40
.github/workflows/monero-book.yml
vendored
Normal file
40
.github/workflows/monero-book.yml
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
# This action attempts to build the Monero book, if changed.
|
||||
|
||||
name: Monero mdBook
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
paths: ['books/protocol/**']
|
||||
pull_request:
|
||||
paths: ['books/protocol/**']
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Version of `mdbook` to install.
|
||||
MDBOOK_VERSION: 0.4.36
|
||||
# Version of `mdbook-svgbob` to install.
|
||||
# <https://github.com/boozook/mdbook-svgbob>.
|
||||
MDBOOK_SVGBOB_VERSION: 0.2.1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/mdbook
|
||||
~/.cargo/bin/mdbook-svgbob
|
||||
key: monero-book
|
||||
|
||||
- name: Install mdBook
|
||||
run: |
|
||||
cargo install --locked --version ${MDBOOK_VERSION} mdbook || echo "mdbook already exists"
|
||||
cargo install --locked --version ${MDBOOK_SVGBOB_VERSION} mdbook-svgbob || echo "mdbook-svgbob already exists"
|
||||
|
||||
- name: Build
|
||||
run: mdbook build books/protocol
|
40
.github/workflows/user-book.yml
vendored
Normal file
40
.github/workflows/user-book.yml
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
# This action attempts to build the user book, if changed.
|
||||
|
||||
name: User mdBook
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
paths: ['books/user/**']
|
||||
pull_request:
|
||||
paths: ['books/user/**']
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Version of `mdbook` to install.
|
||||
MDBOOK_VERSION: 0.4.36
|
||||
# Version of `mdbook-last-changed` to install.
|
||||
# <https://github.com/badboy/mdbook-last-changed>.
|
||||
MDBOOK_LAST_CHANGED_VERSION: 0.1.4
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/mdbook
|
||||
~/.cargo/bin/mdbook-last-changed
|
||||
key: user-book
|
||||
|
||||
- name: Install mdBook
|
||||
run: |
|
||||
cargo install --locked --version ${MDBOOK_VERSION} mdbook || echo "mdbook already exists"
|
||||
cargo install --locked --version ${MDBOOK_LAST_CHANGED_VERSION} mdbook-last-changed || echo "mdbook-last-changed already exists"
|
||||
|
||||
- name: Build
|
||||
run: mdbook build books/user
|
|
@ -216,9 +216,9 @@ The description of pull requests should generally follow the template laid out i
|
|||
If your pull request is long and/or has sections that need clarifying, consider leaving a review on your own PR with comments explaining the changes.
|
||||
|
||||
## 5. Documentation
|
||||
Cuprate's crates (libraries) have inline documentation.
|
||||
Cuprate's crates (libraries) have inline documentation, they are published from the `main` branch at https://doc.cuprate.org.
|
||||
|
||||
These can be built and viewed using the `cargo` tool. For example, to build and view a specific crate's documentation, run the following command at the repository's root:
|
||||
Documentation can be built and viewed using the `cargo` tool. For example, to build and view a specific crate's documentation, run the following command at the repository's root:
|
||||
```bash
|
||||
cargo doc --open --package $CRATE
|
||||
```
|
||||
|
|
1380
Cargo.lock
generated
1380
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
301
Cargo.toml
301
Cargo.toml
|
@ -1,10 +1,12 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# Binaries
|
||||
"binaries/cuprated",
|
||||
# Benchmarks
|
||||
"benches/harness",
|
||||
"benches/harness/lib",
|
||||
"benches/harness/harness-test",
|
||||
"benches/benchmark/bin",
|
||||
"benches/benchmark/lib",
|
||||
"benches/benchmark/example",
|
||||
"benches/criterion/cuprate-json-rpc",
|
||||
# Consensus
|
||||
"consensus",
|
||||
|
@ -23,13 +25,15 @@ members = [
|
|||
"p2p/address-book",
|
||||
# Storage
|
||||
"storage/blockchain",
|
||||
"storage/service",
|
||||
"storage/txpool",
|
||||
"storage/database",
|
||||
# RPC
|
||||
"rpc/json-rpc",
|
||||
"rpc/rpc-types",
|
||||
"rpc/rpc-interface",
|
||||
"rpc/types",
|
||||
"rpc/interface",
|
||||
# Misc
|
||||
"constants",
|
||||
"cryptonight",
|
||||
"helper",
|
||||
"pruning",
|
||||
|
@ -56,52 +60,54 @@ opt-level = 1
|
|||
opt-level = 3
|
||||
|
||||
[workspace.dependencies]
|
||||
async-trait = { version = "0.1.74", default-features = false }
|
||||
bitflags = { version = "2.4.2", default-features = false }
|
||||
borsh = { version = "1.2.1", default-features = false }
|
||||
bytemuck = { version = "1.14.3", default-features = false }
|
||||
bytes = { version = "1.5.0", default-features = false }
|
||||
anyhow = { version = "1.0.89", default-features = false }
|
||||
async-trait = { version = "0.1.82", default-features = false }
|
||||
bitflags = { version = "2.6.0", default-features = false }
|
||||
borsh = { version = "1.5.1", default-features = false }
|
||||
bytemuck = { version = "1.18.0", default-features = false }
|
||||
bytes = { version = "1.7.2", default-features = false }
|
||||
cfg-if = { version = "1.0.0", default-features = false }
|
||||
clap = { version = "4.4.7", default-features = false }
|
||||
chrono = { version = "0.4.31", default-features = false }
|
||||
clap = { version = "4.5.17", default-features = false }
|
||||
chrono = { version = "0.4.38", default-features = false }
|
||||
crypto-bigint = { version = "0.5.5", default-features = false }
|
||||
crossbeam = { version = "0.8.4", default-features = false }
|
||||
curve25519-dalek = { version = "4.1.1", default-features = false }
|
||||
dalek-ff-group = { git = "https://github.com/Cuprate/serai.git", rev = "d27d934", default-features = false }
|
||||
const_format = { version = "0.2.33", default-features = false }
|
||||
curve25519-dalek = { version = "4.1.3", default-features = false }
|
||||
dashmap = { version = "5.5.3", default-features = false }
|
||||
dirs = { version = "5.0.1", default-features = false }
|
||||
futures = { version = "0.3.29", default-features = false }
|
||||
futures = { version = "0.3.30", default-features = false }
|
||||
hex = { version = "0.4.3", default-features = false }
|
||||
hex-literal = { version = "0.4", default-features = false }
|
||||
indexmap = { version = "2.2.5", default-features = false }
|
||||
monero-serai = { git = "https://github.com/Cuprate/serai.git", rev = "d27d934", default-features = false }
|
||||
multiexp = { git = "https://github.com/Cuprate/serai.git", rev = "d27d934", default-features = false }
|
||||
paste = { version = "1.0.14", default-features = false }
|
||||
pin-project = { version = "1.1.3", default-features = false }
|
||||
indexmap = { version = "2.5.0", default-features = false }
|
||||
monero-serai = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce", default-features = false }
|
||||
paste = { version = "1.0.15", default-features = false }
|
||||
pin-project = { version = "1.1.5", default-features = false }
|
||||
randomx-rs = { git = "https://github.com/Cuprate/randomx-rs.git", rev = "0028464", default-features = false }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
rand_distr = { version = "0.4.3", default-features = false }
|
||||
rayon = { version = "1.9.0", default-features = false }
|
||||
serde_bytes = { version = "0.11.12", default-features = false }
|
||||
serde_json = { version = "1.0.108", default-features = false }
|
||||
serde = { version = "1.0.190", default-features = false }
|
||||
thiserror = { version = "1.0.50", default-features = false }
|
||||
thread_local = { version = "1.1.7", default-features = false }
|
||||
tokio-util = { version = "0.7.10", default-features = false }
|
||||
tokio-stream = { version = "0.1.14", default-features = false }
|
||||
tokio = { version = "1.33.0", default-features = false }
|
||||
tower = { version = "0.4.13", default-features = false }
|
||||
tracing-subscriber = { version = "0.3.17", default-features = false }
|
||||
rayon = { version = "1.10.0", default-features = false }
|
||||
serde_bytes = { version = "0.11.15", default-features = false }
|
||||
serde_json = { version = "1.0.128", default-features = false }
|
||||
serde = { version = "1.0.210", default-features = false }
|
||||
thiserror = { version = "1.0.63", default-features = false }
|
||||
thread_local = { version = "1.1.8", default-features = false }
|
||||
tokio-util = { version = "0.7.12", default-features = false }
|
||||
tokio-stream = { version = "0.1.16", default-features = false }
|
||||
tokio = { version = "1.40.0", default-features = false }
|
||||
tower = { git = "https://github.com/Cuprate/tower.git", rev = "6c7faf0", default-features = false } # <https://github.com/tower-rs/tower/pull/796>
|
||||
tracing-subscriber = { version = "0.3.18", default-features = false }
|
||||
tracing = { version = "0.1.40", default-features = false }
|
||||
|
||||
## workspace.dev-dependencies
|
||||
criterion = { version = "0.5.1" }
|
||||
function_name = { version = "0.3.0" }
|
||||
tempfile = { version = "3" }
|
||||
pretty_assertions = { version = "1.4.0" }
|
||||
proptest = { version = "1" }
|
||||
proptest-derive = { version = "0.4.0" }
|
||||
tokio-test = { version = "0.4.4" }
|
||||
criterion = { version = "0.5.1" }
|
||||
function_name = { version = "0.3.0" }
|
||||
tempfile = { version = "3.13.0" }
|
||||
monero-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce" }
|
||||
monero-simple-request-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce" }
|
||||
pretty_assertions = { version = "1.4.1" }
|
||||
proptest = { version = "1" }
|
||||
proptest-derive = { version = "0.4.0" }
|
||||
tokio-test = { version = "0.4.4" }
|
||||
|
||||
## TODO:
|
||||
## Potential dependencies.
|
||||
|
@ -111,4 +117,221 @@ tokio-test = { version = "0.4.4" }
|
|||
# once_cell = { version = "1.18.0" } # Lazy/one-time initialization | https://github.com/matklad/once_cell
|
||||
# open = { version = "5.0.0" } # Open PATH/URL, probably for binaries | https://github.com/byron/open-rs
|
||||
# regex = { version = "1.10.2" } # Regular expressions | https://github.com/rust-lang/regex
|
||||
# ryu = { version = "1.0.15" } # Fast float to string formatting | https://github.com/dtolnay/ryu
|
||||
# ryu = { version = "1.0.15" } # Fast float to string formatting | https://github.com/dtolnay/ryu
|
||||
|
||||
# Lints: cold, warm, hot: <https://github.com/Cuprate/cuprate/issues/131>
|
||||
[workspace.lints.clippy]
|
||||
# Cold
|
||||
borrow_as_ptr = "deny"
|
||||
case_sensitive_file_extension_comparisons = "deny"
|
||||
cast_lossless = "deny"
|
||||
cast_ptr_alignment = "deny"
|
||||
checked_conversions = "deny"
|
||||
cloned_instead_of_copied = "deny"
|
||||
const_is_empty = "deny"
|
||||
doc_lazy_continuation = "deny"
|
||||
doc_link_with_quotes = "deny"
|
||||
duplicated_attributes = "deny"
|
||||
empty_enum = "deny"
|
||||
enum_glob_use = "deny"
|
||||
expl_impl_clone_on_copy = "deny"
|
||||
explicit_into_iter_loop = "deny"
|
||||
filter_map_next = "deny"
|
||||
flat_map_option = "deny"
|
||||
from_iter_instead_of_collect = "deny"
|
||||
if_not_else = "deny"
|
||||
ignored_unit_patterns = "deny"
|
||||
inconsistent_struct_constructor = "deny"
|
||||
index_refutable_slice = "deny"
|
||||
inefficient_to_string = "deny"
|
||||
invalid_upcast_comparisons = "deny"
|
||||
iter_filter_is_ok = "deny"
|
||||
iter_filter_is_some = "deny"
|
||||
implicit_clone = "deny"
|
||||
legacy_numeric_constants = "deny"
|
||||
manual_c_str_literals = "deny"
|
||||
manual_pattern_char_comparison = "deny"
|
||||
manual_instant_elapsed = "deny"
|
||||
manual_inspect = "deny"
|
||||
manual_is_variant_and = "deny"
|
||||
manual_let_else = "deny"
|
||||
manual_ok_or = "deny"
|
||||
manual_string_new = "deny"
|
||||
manual_unwrap_or_default = "deny"
|
||||
map_unwrap_or = "deny"
|
||||
match_bool = "deny"
|
||||
match_same_arms = "deny"
|
||||
match_wildcard_for_single_variants = "deny"
|
||||
mismatching_type_param_order = "deny"
|
||||
missing_transmute_annotations = "deny"
|
||||
mut_mut = "deny"
|
||||
needless_bitwise_bool = "deny"
|
||||
needless_character_iteration = "deny"
|
||||
needless_continue = "deny"
|
||||
needless_for_each = "deny"
|
||||
needless_maybe_sized = "deny"
|
||||
needless_raw_string_hashes = "deny"
|
||||
no_effect_underscore_binding = "deny"
|
||||
no_mangle_with_rust_abi = "deny"
|
||||
option_as_ref_cloned = "deny"
|
||||
option_option = "deny"
|
||||
ptr_as_ptr = "deny"
|
||||
ptr_cast_constness = "deny"
|
||||
pub_underscore_fields = "deny"
|
||||
redundant_closure_for_method_calls = "deny"
|
||||
ref_as_ptr = "deny"
|
||||
ref_option_ref = "deny"
|
||||
same_functions_in_if_condition = "deny"
|
||||
semicolon_if_nothing_returned = "deny"
|
||||
trivially_copy_pass_by_ref = "deny"
|
||||
uninlined_format_args = "deny"
|
||||
unnecessary_join = "deny"
|
||||
unnested_or_patterns = "deny"
|
||||
unused_async = "deny"
|
||||
unused_self = "deny"
|
||||
used_underscore_binding = "deny"
|
||||
zero_sized_map_values = "deny"
|
||||
as_ptr_cast_mut = "deny"
|
||||
clear_with_drain = "deny"
|
||||
collection_is_never_read = "deny"
|
||||
debug_assert_with_mut_call = "deny"
|
||||
derive_partial_eq_without_eq = "deny"
|
||||
empty_line_after_doc_comments = "deny"
|
||||
empty_line_after_outer_attr = "deny"
|
||||
equatable_if_let = "deny"
|
||||
iter_on_empty_collections = "deny"
|
||||
iter_on_single_items = "deny"
|
||||
iter_with_drain = "deny"
|
||||
needless_collect = "deny"
|
||||
needless_pass_by_ref_mut = "deny"
|
||||
negative_feature_names = "deny"
|
||||
non_send_fields_in_send_ty = "deny"
|
||||
nonstandard_macro_braces = "deny"
|
||||
path_buf_push_overwrite = "deny"
|
||||
read_zero_byte_vec = "deny"
|
||||
redundant_clone = "deny"
|
||||
redundant_feature_names = "deny"
|
||||
trailing_empty_array = "deny"
|
||||
trait_duplication_in_bounds = "deny"
|
||||
type_repetition_in_bounds = "deny"
|
||||
uninhabited_references = "deny"
|
||||
unnecessary_struct_initialization = "deny"
|
||||
unused_peekable = "deny"
|
||||
unused_rounding = "deny"
|
||||
use_self = "deny"
|
||||
useless_let_if_seq = "deny"
|
||||
wildcard_dependencies = "deny"
|
||||
unseparated_literal_suffix = "deny"
|
||||
unnecessary_safety_doc = "deny"
|
||||
unnecessary_safety_comment = "deny"
|
||||
unnecessary_self_imports = "deny"
|
||||
string_to_string = "deny"
|
||||
rest_pat_in_fully_bound_structs = "deny"
|
||||
redundant_type_annotations = "deny"
|
||||
infinite_loop = "deny"
|
||||
zero_repeat_side_effects = "deny"
|
||||
|
||||
# Warm
|
||||
cast_possible_truncation = "deny"
|
||||
cast_possible_wrap = "deny"
|
||||
cast_precision_loss = "deny"
|
||||
cast_sign_loss = "deny"
|
||||
copy_iterator = "deny"
|
||||
doc_markdown = "deny"
|
||||
explicit_deref_methods = "deny"
|
||||
explicit_iter_loop = "deny"
|
||||
float_cmp = "deny"
|
||||
fn_params_excessive_bools = "deny"
|
||||
into_iter_without_iter = "deny"
|
||||
iter_without_into_iter = "deny"
|
||||
iter_not_returning_iterator = "deny"
|
||||
large_digit_groups = "deny"
|
||||
large_types_passed_by_value = "deny"
|
||||
manual_assert = "deny"
|
||||
maybe_infinite_iter = "deny"
|
||||
missing_fields_in_debug = "deny"
|
||||
needless_pass_by_value = "deny"
|
||||
range_minus_one = "deny"
|
||||
range_plus_one = "deny"
|
||||
redundant_else = "deny"
|
||||
ref_binding_to_reference = "deny"
|
||||
return_self_not_must_use = "deny"
|
||||
single_match_else = "deny"
|
||||
string_add_assign = "deny"
|
||||
transmute_ptr_to_ptr = "deny"
|
||||
unchecked_duration_subtraction = "deny"
|
||||
unnecessary_box_returns = "deny"
|
||||
unnecessary_wraps = "deny"
|
||||
branches_sharing_code = "deny"
|
||||
fallible_impl_from = "deny"
|
||||
missing_const_for_fn = "deny"
|
||||
significant_drop_in_scrutinee = "deny"
|
||||
significant_drop_tightening = "deny"
|
||||
try_err = "deny"
|
||||
lossy_float_literal = "deny"
|
||||
let_underscore_must_use = "deny"
|
||||
iter_over_hash_type = "deny"
|
||||
get_unwrap = "deny"
|
||||
error_impl_error = "deny"
|
||||
empty_structs_with_brackets = "deny"
|
||||
empty_enum_variants_with_brackets = "deny"
|
||||
empty_drop = "deny"
|
||||
clone_on_ref_ptr = "deny"
|
||||
upper_case_acronyms = "deny"
|
||||
allow_attributes = "deny"
|
||||
|
||||
# Hot
|
||||
# inline_always = "deny"
|
||||
# large_futures = "deny"
|
||||
# large_stack_arrays = "deny"
|
||||
# linkedlist = "deny"
|
||||
# missing_errors_doc = "deny"
|
||||
# missing_panics_doc = "deny"
|
||||
# should_panic_without_expect = "deny"
|
||||
# similar_names = "deny"
|
||||
# too_many_lines = "deny"
|
||||
# unreadable_literal = "deny"
|
||||
# wildcard_imports = "deny"
|
||||
# allow_attributes_without_reason = "deny"
|
||||
# missing_assert_message = "deny"
|
||||
# missing_docs_in_private_items = "deny"
|
||||
undocumented_unsafe_blocks = "deny"
|
||||
# multiple_unsafe_ops_per_block = "deny"
|
||||
# single_char_lifetime_names = "deny"
|
||||
# wildcard_enum_match_arm = "deny"
|
||||
|
||||
[workspace.lints.rust]
|
||||
# Cold
|
||||
future_incompatible = { level = "deny", priority = -1 }
|
||||
nonstandard_style = { level = "deny", priority = -1 }
|
||||
absolute_paths_not_starting_with_crate = "deny"
|
||||
explicit_outlives_requirements = "deny"
|
||||
keyword_idents_2018 = "deny"
|
||||
keyword_idents_2024 = "deny"
|
||||
missing_abi = "deny"
|
||||
non_ascii_idents = "deny"
|
||||
non_local_definitions = "deny"
|
||||
redundant_lifetimes = "deny"
|
||||
single_use_lifetimes = "deny"
|
||||
trivial_casts = "deny"
|
||||
trivial_numeric_casts = "deny"
|
||||
unsafe_op_in_unsafe_fn = "deny"
|
||||
unused_crate_dependencies = "deny"
|
||||
unused_import_braces = "deny"
|
||||
unused_lifetimes = "deny"
|
||||
unused_macro_rules = "deny"
|
||||
ambiguous_glob_imports = "deny"
|
||||
unused_unsafe = "deny"
|
||||
|
||||
# Warm
|
||||
let_underscore = { level = "deny", priority = -1 }
|
||||
unreachable_pub = "deny"
|
||||
unused_qualifications = "deny"
|
||||
variant_size_differences = "deny"
|
||||
non_camel_case_types = "deny"
|
||||
|
||||
# Hot
|
||||
# unused_results = "deny"
|
||||
# non_exhaustive_omitted_patterns = "deny"
|
||||
# missing_docs = "deny"
|
||||
# missing_copy_implementations = "deny"
|
||||
|
|
|
@ -49,7 +49,7 @@ Cuprate maintains various documentation books:
|
|||
| [Monero's protocol book](https://monero-book.cuprate.org) | Documents the Monero protocol |
|
||||
| [Cuprate's user book](https://user.cuprate.org) | Practical user-guide for using `cuprated` |
|
||||
|
||||
For crate (library) documentation, see the `Documentation` section in [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
||||
For crate (library) documentation, see: https://doc.cuprate.org. This site holds documentation for Cuprate's crates and all dependencies. All Cuprate crates start with `cuprate_`, for example: [`cuprate_database`](https://doc.cuprate.org/cuprate_database).
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
28
benches/benchmark/bin/Cargo.toml
Normal file
28
benches/benchmark/bin/Cargo.toml
Normal file
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "cuprate-benchmark"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Cuprate's benchmarking binary"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/bin"
|
||||
keywords = ["cuprate", "benchmarking", "binary"]
|
||||
|
||||
[features]
|
||||
default = ["example"]
|
||||
example = ["dep:cuprate-benchmark-example"]
|
||||
database = ["dep:cuprate-database"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-benchmark-lib = { path = "../lib" }
|
||||
cuprate-benchmark-example = { path = "../example", optional = true }
|
||||
cuprate-database = { path = "../../../storage/database", optional = true }
|
||||
|
||||
cfg-if = { workspace = true }
|
||||
# serde = { workspace = true, features = ["derive"] }
|
||||
# serde_json = { workspace = true, features = ["std"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
1
benches/benchmark/bin/README.md
Normal file
1
benches/benchmark/bin/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
## `cuprate-benchmark`
|
66
benches/benchmark/bin/src/main.rs
Normal file
66
benches/benchmark/bin/src/main.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![allow(
|
||||
unused_crate_dependencies,
|
||||
reason = "this crate imports many potentially unused dependencies"
|
||||
)]
|
||||
|
||||
use std::{collections::HashMap, io::Write};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
use cuprate_benchmark_lib::Benchmark;
|
||||
|
||||
fn main() {
|
||||
let mut timings = HashMap::new();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(any(feature = "database", feature = "example")))] {
|
||||
compile_error!("[cuprate_benchmark]: no feature specified. Use `--features $BENCHMARK_FEATURE` when building.");
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "database")] {
|
||||
run_benchmark::<cuprate_benchmark_database::Benchmark>(&mut timings);
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "example")] {
|
||||
run_benchmark::<cuprate_benchmark_example::Example>(&mut timings);
|
||||
}
|
||||
}
|
||||
|
||||
print_timings(&timings);
|
||||
}
|
||||
|
||||
fn run_benchmark<B: Benchmark>(timings: &mut HashMap<&'static str, f32>) {
|
||||
let name = std::any::type_name::<B>();
|
||||
|
||||
print!("{name:>34} ... ");
|
||||
std::io::stdout().flush().unwrap();
|
||||
|
||||
let input = B::SETUP();
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
B::MAIN(input);
|
||||
let time = now.elapsed().as_secs_f32();
|
||||
|
||||
println!("{time}");
|
||||
assert!(
|
||||
timings.insert(name, time).is_none(),
|
||||
"[cuprate_benchmark]: there were 2 benchmarks with the same name - this collides the final output: {name}",
|
||||
);
|
||||
}
|
||||
|
||||
fn print_timings(timings: &HashMap<&'static str, f32>) {
|
||||
let mut s = String::new();
|
||||
s.push_str("| Benchmark | Time (seconds) |\n");
|
||||
s.push_str("|------------------------------------|----------------|");
|
||||
#[expect(clippy::iter_over_hash_type)]
|
||||
for (k, v) in timings {
|
||||
s += &format!("\n| {k:<34} | {v:<14} |");
|
||||
}
|
||||
|
||||
println!("\n{s}");
|
||||
}
|
17
benches/benchmark/example/Cargo.toml
Normal file
17
benches/benchmark/example/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "cuprate-benchmark-example"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Example showcasing Cuprate's benchmarking harness"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/example"
|
||||
keywords = ["cuprate", "benchmarking", "example"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-benchmark-lib = { path = "../lib" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
1
benches/benchmark/example/README.md
Normal file
1
benches/benchmark/example/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
## `cuprate-benchmark-example`
|
10
benches/benchmark/example/src/lib.rs
Normal file
10
benches/benchmark/example/src/lib.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
|
||||
/// TODO
|
||||
pub struct Example;
|
||||
|
||||
impl cuprate_benchmark_lib::Benchmark for Example {
|
||||
type Input = ();
|
||||
const SETUP: fn() -> Self::Input = || {};
|
||||
const MAIN: fn(Self::Input) = |()| {};
|
||||
}
|
18
benches/benchmark/lib/Cargo.toml
Normal file
18
benches/benchmark/lib/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "cuprate-benchmark-lib"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Cuprate's benchmarking library"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/lib"
|
||||
keywords = ["cuprate", "benchmarking", "library"]
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
1
benches/benchmark/lib/README.md
Normal file
1
benches/benchmark/lib/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
## `cuprate-benchmark-lib`
|
|
@ -1,16 +1,21 @@
|
|||
//! TODO
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Use
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- trait Benchmark
|
||||
/// A benchmarking function and its inputs.
|
||||
pub trait Benchmark {
|
||||
/// Input to the main benchmarking function.
|
||||
///
|
||||
/// This is passed to [`Self::MAIN`].
|
||||
type Input;
|
||||
|
||||
/// Setup function to generate the input.
|
||||
///
|
||||
/// This function is not timed.
|
||||
const SETUP: fn() -> Self::Input;
|
||||
|
||||
/// The main function to benchmark.
|
||||
///
|
||||
/// The start of the timer begins right before
|
||||
/// this function is called and ends after the
|
||||
/// function returns.
|
||||
const MAIN: fn(Self::Input);
|
||||
}
|
5
benches/benchmark/lib/src/lib.rs
Normal file
5
benches/benchmark/lib/src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
|
||||
mod benchmark;
|
||||
|
||||
pub use benchmark::Benchmark;
|
|
@ -1,23 +0,0 @@
|
|||
[package]
|
||||
name = "cuprate-harness"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Cuprate's benchmarking harness binary"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/harness"
|
||||
keywords = ["cuprate", "benchmarking", "harness", "binary"]
|
||||
|
||||
[features]
|
||||
default = ["test"]
|
||||
test = ["dep:cuprate-harness-test"]
|
||||
database = ["dep:cuprate-database"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-harness-lib = { path = "lib" }
|
||||
cuprate-harness-test = { path = "harness-test", optional = true }
|
||||
cuprate-database = { path = "../../storage/database", optional = true }
|
||||
|
||||
cfg-if = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
|
@ -1,14 +0,0 @@
|
|||
[package]
|
||||
name = "cuprate-harness-test"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Test for Cuprate's benchmarking harness"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/macro/harness-test"
|
||||
keywords = ["cuprate", "benchmarking", "harness", "test"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-harness-lib = { path = "../lib" }
|
||||
|
||||
[dev-dependencies]
|
|
@ -1,16 +0,0 @@
|
|||
//! TODO
|
||||
|
||||
/// TODO
|
||||
pub struct BenchmarkHarnessTest;
|
||||
|
||||
// TODO
|
||||
impl cuprate_harness_lib::Benchmark for BenchmarkHarnessTest {
|
||||
/// TODO
|
||||
type Input = ();
|
||||
|
||||
/// TODO
|
||||
const SETUP: fn() -> Self::Input = || {};
|
||||
|
||||
/// TODO
|
||||
const MAIN: fn(Self::Input) = |_| {};
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
[package]
|
||||
name = "cuprate-harness-lib"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
description = "Cuprate's benchmarking harness library"
|
||||
license = "MIT"
|
||||
authors = ["hinto-janai"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/harness/core"
|
||||
keywords = ["cuprate", "benchmarking", "harness", "library"]
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
|
@ -1,97 +0,0 @@
|
|||
//! TODO
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
clippy::missing_docs_in_private_items,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints when running in debug mode.
|
||||
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Modules
|
||||
mod benchmark;
|
||||
pub use benchmark::Benchmark;
|
|
@ -1,120 +0,0 @@
|
|||
//! TODO
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
clippy::missing_docs_in_private_items,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints when running in debug mode.
|
||||
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Modules
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "database")] {
|
||||
use cuprate_harness_database::BenchmarkDatabase as B;
|
||||
} else if #[cfg(feature = "test")] {
|
||||
use cuprate_harness_test::BenchmarkHarnessTest as B;
|
||||
} else {
|
||||
compile_error!("cuprate_harness: no feature specified. Use `--features $YOUR_CRATE_BENCHMARK_NAME` when building.");
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Main
|
||||
use cuprate_harness_lib::Benchmark;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Main
|
||||
|
||||
#[allow(clippy::let_unit_value)]
|
||||
fn main() {
|
||||
let input = B::SETUP();
|
||||
let name = std::any::type_name::<B>();
|
||||
println!("[Cuprate Harness] {name}");
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
B::MAIN(input);
|
||||
println!("{}", now.elapsed().as_secs_f32());
|
||||
}
|
77
binaries/cuprated/Cargo.toml
Normal file
77
binaries/cuprated/Cargo.toml
Normal file
|
@ -0,0 +1,77 @@
|
|||
[package]
|
||||
name = "cuprated"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
description = "The Cuprate Monero Rust node."
|
||||
license = "AGPL-3.0-only"
|
||||
authors = ["Boog900", "hinto-janai", "SyntheticBird45"]
|
||||
repository = "https://github.com/Cuprate/cuprate/tree/main/binaries/cuprated"
|
||||
|
||||
[dependencies]
|
||||
# TODO: after v1.0.0, remove unneeded dependencies.
|
||||
cuprate-consensus = { path = "../../consensus" }
|
||||
cuprate-fast-sync = { path = "../../consensus/fast-sync" }
|
||||
cuprate-consensus-rules = { path = "../../consensus/rules" }
|
||||
cuprate-cryptonight = { path = "../../cryptonight" }
|
||||
cuprate-helper = { path = "../../helper" }
|
||||
cuprate-epee-encoding = { path = "../../net/epee-encoding" }
|
||||
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
|
||||
cuprate-levin = { path = "../../net/levin" }
|
||||
cuprate-wire = { path = "../../net/wire" }
|
||||
cuprate-p2p = { path = "../../p2p/p2p" }
|
||||
cuprate-p2p-core = { path = "../../p2p/p2p-core" }
|
||||
cuprate-dandelion-tower = { path = "../../p2p/dandelion-tower" }
|
||||
cuprate-async-buffer = { path = "../../p2p/async-buffer" }
|
||||
cuprate-address-book = { path = "../../p2p/address-book" }
|
||||
cuprate-blockchain = { path = "../../storage/blockchain" }
|
||||
cuprate-database-service = { path = "../../storage/service" }
|
||||
cuprate-txpool = { path = "../../storage/txpool" }
|
||||
cuprate-database = { path = "../../storage/database" }
|
||||
cuprate-pruning = { path = "../../pruning" }
|
||||
cuprate-test-utils = { path = "../../test-utils" }
|
||||
cuprate-types = { path = "../../types" }
|
||||
cuprate-json-rpc = { path = "../../rpc/json-rpc" }
|
||||
cuprate-rpc-interface = { path = "../../rpc/interface" }
|
||||
cuprate-rpc-types = { path = "../../rpc/types" }
|
||||
|
||||
# TODO: after v1.0.0, remove unneeded dependencies.
|
||||
anyhow = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
borsh = { workspace = true }
|
||||
bytemuck = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
cfg-if = { workspace = true }
|
||||
clap = { workspace = true, features = ["cargo"] }
|
||||
chrono = { workspace = true }
|
||||
crypto-bigint = { workspace = true }
|
||||
crossbeam = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
const_format = { workspace = true }
|
||||
dashmap = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
hex-literal = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
pin-project = { workspace = true }
|
||||
randomx-rs = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
rand_distr = { workspace = true }
|
||||
rayon = { workspace = true }
|
||||
serde_bytes = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
thread_local = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tower = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
2
binaries/cuprated/README.md
Normal file
2
binaries/cuprated/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# `cuprated`
|
||||
TODO
|
6
binaries/cuprated/src/blockchain.rs
Normal file
6
binaries/cuprated/src/blockchain.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
//! Blockchain
|
||||
//!
|
||||
//! Will contain the chain manager and syncer.
|
||||
|
||||
mod manager;
|
||||
mod syncer;
|
1
binaries/cuprated/src/config.rs
Normal file
1
binaries/cuprated/src/config.rs
Normal file
|
@ -0,0 +1 @@
|
|||
//! cuprated config
|
34
binaries/cuprated/src/constants.rs
Normal file
34
binaries/cuprated/src/constants.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
//! General constants used throughout `cuprated`.
|
||||
|
||||
use const_format::formatcp;
|
||||
|
||||
/// `cuprated`'s semantic version (`MAJOR.MINOR.PATCH`) as string.
|
||||
pub const VERSION: &str = clap::crate_version!();
|
||||
|
||||
/// [`VERSION`] + the build type.
|
||||
///
|
||||
/// If a debug build, the suffix is `-debug`, else it is `-release`.
|
||||
pub const VERSION_BUILD: &str = if cfg!(debug_assertions) {
|
||||
formatcp!("{VERSION}-debug")
|
||||
} else {
|
||||
formatcp!("{VERSION}-release")
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn version() {
|
||||
assert_eq!(VERSION, "0.0.1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_build() {
|
||||
if cfg!(debug_assertions) {
|
||||
assert_eq!(VERSION_BUILD, "0.0.1-debug");
|
||||
} else {
|
||||
assert_eq!(VERSION_BUILD, "0.0.1-release");
|
||||
}
|
||||
}
|
||||
}
|
28
binaries/cuprated/src/main.rs
Normal file
28
binaries/cuprated/src/main.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![allow(
|
||||
unused_imports,
|
||||
unreachable_pub,
|
||||
unused_crate_dependencies,
|
||||
dead_code,
|
||||
unused_variables,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::unused_async,
|
||||
reason = "TODO: remove after v1.0.0"
|
||||
)]
|
||||
|
||||
mod blockchain;
|
||||
mod config;
|
||||
mod constants;
|
||||
mod p2p;
|
||||
mod rpc;
|
||||
mod statics;
|
||||
mod txpool;
|
||||
|
||||
fn main() {
|
||||
// Initialize global static `LazyLock` data.
|
||||
statics::init_lazylock_statics();
|
||||
|
||||
// TODO: everything else.
|
||||
todo!()
|
||||
}
|
5
binaries/cuprated/src/p2p.rs
Normal file
5
binaries/cuprated/src/p2p.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
//! P2P
|
||||
//!
|
||||
//! Will handle initiating the P2P and contains a protocol request handler.
|
||||
|
||||
mod request_handler;
|
1
binaries/cuprated/src/p2p/request_handler.rs
Normal file
1
binaries/cuprated/src/p2p/request_handler.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
10
binaries/cuprated/src/rpc.rs
Normal file
10
binaries/cuprated/src/rpc.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
//! RPC
|
||||
//!
|
||||
//! Will contain the code to initiate the RPC and a request handler.
|
||||
|
||||
mod bin;
|
||||
mod handler;
|
||||
mod json;
|
||||
mod other;
|
||||
|
||||
pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState};
|
85
binaries/cuprated/src/rpc/bin.rs
Normal file
85
binaries/cuprated/src/rpc/bin.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use anyhow::Error;
|
||||
|
||||
use cuprate_rpc_types::{
|
||||
bin::{
|
||||
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksByHeightResponse,
|
||||
GetBlocksRequest, GetBlocksResponse, GetHashesRequest, GetHashesResponse,
|
||||
GetOutputIndexesRequest, GetOutputIndexesResponse, GetOutsRequest, GetOutsResponse,
|
||||
GetTransactionPoolHashesRequest, GetTransactionPoolHashesResponse,
|
||||
},
|
||||
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
||||
};
|
||||
|
||||
use crate::rpc::CupratedRpcHandlerState;
|
||||
|
||||
/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: BinRequest,
|
||||
) -> Result<BinResponse, Error> {
|
||||
use BinRequest as Req;
|
||||
use BinResponse as Resp;
|
||||
|
||||
Ok(match request {
|
||||
Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r).await?),
|
||||
Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r).await?),
|
||||
Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r).await?),
|
||||
Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r).await?),
|
||||
Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r).await?),
|
||||
Req::GetTransactionPoolHashes(r) => {
|
||||
Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?)
|
||||
}
|
||||
Req::GetOutputDistribution(r) => {
|
||||
Resp::GetOutputDistribution(get_output_distribution(state, r).await?)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlocksRequest,
|
||||
) -> Result<GetBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_blocks_by_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlocksByHeightRequest,
|
||||
) -> Result<GetBlocksByHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetHashesRequest,
|
||||
) -> Result<GetHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_indexes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetOutputIndexesRequest,
|
||||
) -> Result<GetOutputIndexesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_outs(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetOutsRequest,
|
||||
) -> Result<GetOutsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionPoolHashesRequest,
|
||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_distribution(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetOutputDistributionRequest,
|
||||
) -> Result<GetOutputDistributionResponse, Error> {
|
||||
todo!()
|
||||
}
|
103
binaries/cuprated/src/rpc/handler.rs
Normal file
103
binaries/cuprated/src/rpc/handler.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
//! Dummy implementation of [`RpcHandler`].
|
||||
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::Error;
|
||||
use futures::{channel::oneshot::channel, future::BoxFuture};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tower::Service;
|
||||
|
||||
use cuprate_blockchain::service::BlockchainReadHandle;
|
||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||
use cuprate_json_rpc::Id;
|
||||
use cuprate_rpc_interface::RpcHandler;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{BinRequest, BinResponse},
|
||||
json::{JsonRpcRequest, JsonRpcResponse},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
};
|
||||
use cuprate_txpool::service::TxpoolReadHandle;
|
||||
|
||||
use crate::rpc::{bin, json, other};
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone)]
|
||||
pub struct CupratedRpcHandler {
|
||||
/// Should this RPC server be [restricted](RpcHandler::restricted)?
|
||||
//
|
||||
// INVARIANT:
|
||||
// We don't need to include this in `state` and check for
|
||||
// `self.is_restricted()` because `cuprate-rpc-interface` handles that.
|
||||
pub restricted: bool,
|
||||
|
||||
/// State needed for request -> response mapping.
|
||||
pub state: CupratedRpcHandlerState,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone)]
|
||||
pub struct CupratedRpcHandlerState {
|
||||
/// Read handle to the blockchain database.
|
||||
pub blockchain: BlockchainReadHandle,
|
||||
|
||||
/// Read handle to the transaction pool database.
|
||||
pub txpool: TxpoolReadHandle,
|
||||
}
|
||||
|
||||
impl CupratedRpcHandler {
|
||||
/// TODO
|
||||
pub fn init() {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl RpcHandler for CupratedRpcHandler {
|
||||
fn restricted(&self) -> bool {
|
||||
self.restricted
|
||||
}
|
||||
}
|
||||
|
||||
impl Service<JsonRpcRequest> for CupratedRpcHandler {
|
||||
type Response = JsonRpcResponse;
|
||||
type Error = Error;
|
||||
type Future = BoxFuture<'static, Result<JsonRpcResponse, Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, request: JsonRpcRequest) -> Self::Future {
|
||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||
Box::pin(json::map_request(state, request))
|
||||
}
|
||||
}
|
||||
|
||||
impl Service<BinRequest> for CupratedRpcHandler {
|
||||
type Response = BinResponse;
|
||||
type Error = Error;
|
||||
type Future = BoxFuture<'static, Result<BinResponse, Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, request: BinRequest) -> Self::Future {
|
||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||
Box::pin(bin::map_request(state, request))
|
||||
}
|
||||
}
|
||||
|
||||
impl Service<OtherRequest> for CupratedRpcHandler {
|
||||
type Response = OtherResponse;
|
||||
type Error = Error;
|
||||
type Future = BoxFuture<'static, Result<OtherResponse, Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, request: OtherRequest) -> Self::Future {
|
||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||
Box::pin(other::map_request(state, request))
|
||||
}
|
||||
}
|
294
binaries/cuprated/src/rpc/json.rs
Normal file
294
binaries/cuprated/src/rpc/json.rs
Normal file
|
@ -0,0 +1,294 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Error;
|
||||
use tower::ServiceExt;
|
||||
|
||||
use cuprate_rpc_types::json::{
|
||||
AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest,
|
||||
CalcPowResponse, FlushCacheRequest, FlushCacheResponse, FlushTransactionPoolRequest,
|
||||
FlushTransactionPoolResponse, GenerateBlocksRequest, GenerateBlocksResponse,
|
||||
GetAlternateChainsRequest, GetAlternateChainsResponse, GetBansRequest, GetBansResponse,
|
||||
GetBlockCountRequest, GetBlockCountResponse, GetBlockHeaderByHashRequest,
|
||||
GetBlockHeaderByHashResponse, GetBlockHeaderByHeightRequest, GetBlockHeaderByHeightResponse,
|
||||
GetBlockHeadersRangeRequest, GetBlockHeadersRangeResponse, GetBlockRequest, GetBlockResponse,
|
||||
GetCoinbaseTxSumRequest, GetCoinbaseTxSumResponse, GetConnectionsRequest,
|
||||
GetConnectionsResponse, GetFeeEstimateRequest, GetFeeEstimateResponse, GetInfoRequest,
|
||||
GetInfoResponse, GetLastBlockHeaderRequest, GetLastBlockHeaderResponse, GetMinerDataRequest,
|
||||
GetMinerDataResponse, GetOutputHistogramRequest, GetOutputHistogramResponse,
|
||||
GetTransactionPoolBacklogRequest, GetTransactionPoolBacklogResponse, GetTxIdsLooseRequest,
|
||||
GetTxIdsLooseResponse, GetVersionRequest, GetVersionResponse, HardForkInfoRequest,
|
||||
HardForkInfoResponse, JsonRpcRequest, JsonRpcResponse, OnGetBlockHashRequest,
|
||||
OnGetBlockHashResponse, PruneBlockchainRequest, PruneBlockchainResponse, RelayTxRequest,
|
||||
RelayTxResponse, SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse,
|
||||
SyncInfoRequest, SyncInfoResponse,
|
||||
};
|
||||
|
||||
use crate::rpc::CupratedRpcHandlerState;
|
||||
|
||||
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: JsonRpcRequest,
|
||||
) -> Result<JsonRpcResponse, Error> {
|
||||
use JsonRpcRequest as Req;
|
||||
use JsonRpcResponse as Resp;
|
||||
|
||||
Ok(match request {
|
||||
Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r).await?),
|
||||
Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r).await?),
|
||||
Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r).await?),
|
||||
Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r).await?),
|
||||
Req::GetLastBlockHeader(r) => {
|
||||
Resp::GetLastBlockHeader(get_last_block_header(state, r).await?)
|
||||
}
|
||||
Req::GetBlockHeaderByHash(r) => {
|
||||
Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r).await?)
|
||||
}
|
||||
Req::GetBlockHeaderByHeight(r) => {
|
||||
Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r).await?)
|
||||
}
|
||||
Req::GetBlockHeadersRange(r) => {
|
||||
Resp::GetBlockHeadersRange(get_block_headers_range(state, r).await?)
|
||||
}
|
||||
Req::GetBlock(r) => Resp::GetBlock(get_block(state, r).await?),
|
||||
Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r).await?),
|
||||
Req::GetInfo(r) => Resp::GetInfo(get_info(state, r).await?),
|
||||
Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r).await?),
|
||||
Req::SetBans(r) => Resp::SetBans(set_bans(state, r).await?),
|
||||
Req::GetBans(r) => Resp::GetBans(get_bans(state, r).await?),
|
||||
Req::Banned(r) => Resp::Banned(banned(state, r).await?),
|
||||
Req::FlushTransactionPool(r) => {
|
||||
Resp::FlushTransactionPool(flush_transaction_pool(state, r).await?)
|
||||
}
|
||||
Req::GetOutputHistogram(r) => {
|
||||
Resp::GetOutputHistogram(get_output_histogram(state, r).await?)
|
||||
}
|
||||
Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r).await?),
|
||||
Req::GetVersion(r) => Resp::GetVersion(get_version(state, r).await?),
|
||||
Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r).await?),
|
||||
Req::GetAlternateChains(r) => {
|
||||
Resp::GetAlternateChains(get_alternate_chains(state, r).await?)
|
||||
}
|
||||
Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r).await?),
|
||||
Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r).await?),
|
||||
Req::GetTransactionPoolBacklog(r) => {
|
||||
Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r).await?)
|
||||
}
|
||||
Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r).await?),
|
||||
Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r).await?),
|
||||
Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r).await?),
|
||||
Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r).await?),
|
||||
Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r).await?),
|
||||
Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r).await?),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_block_count(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlockCountRequest,
|
||||
) -> Result<GetBlockCountResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn on_get_block_hash(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: OnGetBlockHashRequest,
|
||||
) -> Result<OnGetBlockHashResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn submit_block(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SubmitBlockRequest,
|
||||
) -> Result<SubmitBlockResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn generate_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GenerateBlocksRequest,
|
||||
) -> Result<GenerateBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_last_block_header(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetLastBlockHeaderRequest,
|
||||
) -> Result<GetLastBlockHeaderResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_header_by_hash(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlockHeaderByHashRequest,
|
||||
) -> Result<GetBlockHeaderByHashResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_header_by_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlockHeaderByHeightRequest,
|
||||
) -> Result<GetBlockHeaderByHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_headers_range(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlockHeadersRangeRequest,
|
||||
) -> Result<GetBlockHeadersRangeResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBlockRequest,
|
||||
) -> Result<GetBlockResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_connections(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetConnectionsRequest,
|
||||
) -> Result<GetConnectionsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetInfoRequest,
|
||||
) -> Result<GetInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn hard_fork_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: HardForkInfoRequest,
|
||||
) -> Result<HardForkInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_bans(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetBansRequest,
|
||||
) -> Result<SetBansResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_bans(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetBansRequest,
|
||||
) -> Result<GetBansResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn banned(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: BannedRequest,
|
||||
) -> Result<BannedResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn flush_transaction_pool(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: FlushTransactionPoolRequest,
|
||||
) -> Result<FlushTransactionPoolResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_histogram(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetOutputHistogramRequest,
|
||||
) -> Result<GetOutputHistogramResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_coinbase_tx_sum(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetCoinbaseTxSumRequest,
|
||||
) -> Result<GetCoinbaseTxSumResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_version(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetVersionRequest,
|
||||
) -> Result<GetVersionResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_fee_estimate(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetFeeEstimateRequest,
|
||||
) -> Result<GetFeeEstimateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_alternate_chains(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetAlternateChainsRequest,
|
||||
) -> Result<GetAlternateChainsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn relay_tx(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: RelayTxRequest,
|
||||
) -> Result<RelayTxResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn sync_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SyncInfoRequest,
|
||||
) -> Result<SyncInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_backlog(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionPoolBacklogRequest,
|
||||
) -> Result<GetTransactionPoolBacklogResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_miner_data(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetMinerDataRequest,
|
||||
) -> Result<GetMinerDataResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn prune_blockchain(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: PruneBlockchainRequest,
|
||||
) -> Result<PruneBlockchainResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn calc_pow(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: CalcPowRequest,
|
||||
) -> Result<CalcPowResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn flush_cache(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: FlushCacheRequest,
|
||||
) -> Result<FlushCacheResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn add_aux_pow(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: AddAuxPowRequest,
|
||||
) -> Result<AddAuxPowResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_tx_ids_loose(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTxIdsLooseRequest,
|
||||
) -> Result<GetTxIdsLooseResponse, Error> {
|
||||
todo!()
|
||||
}
|
260
binaries/cuprated/src/rpc/other.rs
Normal file
260
binaries/cuprated/src/rpc/other.rs
Normal file
|
@ -0,0 +1,260 @@
|
|||
use anyhow::Error;
|
||||
|
||||
use cuprate_rpc_types::other::{
|
||||
GetAltBlocksHashesRequest, GetAltBlocksHashesResponse, GetHeightRequest, GetHeightResponse,
|
||||
GetLimitRequest, GetLimitResponse, GetNetStatsRequest, GetNetStatsResponse, GetOutsRequest,
|
||||
GetOutsResponse, GetPeerListRequest, GetPeerListResponse, GetPublicNodesRequest,
|
||||
GetPublicNodesResponse, GetTransactionPoolHashesRequest, GetTransactionPoolHashesResponse,
|
||||
GetTransactionPoolRequest, GetTransactionPoolResponse, GetTransactionPoolStatsRequest,
|
||||
GetTransactionPoolStatsResponse, GetTransactionsRequest, GetTransactionsResponse,
|
||||
InPeersRequest, InPeersResponse, IsKeyImageSpentRequest, IsKeyImageSpentResponse,
|
||||
MiningStatusRequest, MiningStatusResponse, OtherRequest, OtherResponse, OutPeersRequest,
|
||||
OutPeersResponse, PopBlocksRequest, PopBlocksResponse, SaveBcRequest, SaveBcResponse,
|
||||
SendRawTransactionRequest, SendRawTransactionResponse, SetBootstrapDaemonRequest,
|
||||
SetBootstrapDaemonResponse, SetLimitRequest, SetLimitResponse, SetLogCategoriesRequest,
|
||||
SetLogCategoriesResponse, SetLogHashRateRequest, SetLogHashRateResponse, SetLogLevelRequest,
|
||||
SetLogLevelResponse, StartMiningRequest, StartMiningResponse, StopDaemonRequest,
|
||||
StopDaemonResponse, StopMiningRequest, StopMiningResponse, UpdateRequest, UpdateResponse,
|
||||
};
|
||||
|
||||
use crate::rpc::CupratedRpcHandlerState;
|
||||
|
||||
/// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: OtherRequest,
|
||||
) -> Result<OtherResponse, Error> {
|
||||
use OtherRequest as Req;
|
||||
use OtherResponse as Resp;
|
||||
|
||||
Ok(match request {
|
||||
Req::GetHeight(r) => Resp::GetHeight(get_height(state, r).await?),
|
||||
Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r).await?),
|
||||
Req::GetAltBlocksHashes(r) => {
|
||||
Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r).await?)
|
||||
}
|
||||
Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r).await?),
|
||||
Req::SendRawTransaction(r) => {
|
||||
Resp::SendRawTransaction(send_raw_transaction(state, r).await?)
|
||||
}
|
||||
Req::StartMining(r) => Resp::StartMining(start_mining(state, r).await?),
|
||||
Req::StopMining(r) => Resp::StopMining(stop_mining(state, r).await?),
|
||||
Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r).await?),
|
||||
Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r).await?),
|
||||
Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r).await?),
|
||||
Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r).await?),
|
||||
Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r).await?),
|
||||
Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r).await?),
|
||||
Req::SetBootstrapDaemon(r) => {
|
||||
Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r).await?)
|
||||
}
|
||||
Req::GetTransactionPool(r) => {
|
||||
Resp::GetTransactionPool(get_transaction_pool(state, r).await?)
|
||||
}
|
||||
Req::GetTransactionPoolStats(r) => {
|
||||
Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r).await?)
|
||||
}
|
||||
Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r).await?),
|
||||
Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r).await?),
|
||||
Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r).await?),
|
||||
Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r).await?),
|
||||
Req::InPeers(r) => Resp::InPeers(in_peers(state, r).await?),
|
||||
Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r).await?),
|
||||
Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r).await?),
|
||||
Req::Update(r) => Resp::Update(update(state, r).await?),
|
||||
Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r).await?),
|
||||
Req::GetTransactionPoolHashes(r) => {
|
||||
Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?)
|
||||
}
|
||||
Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r).await?),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetHeightRequest,
|
||||
) -> Result<GetHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transactions(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionsRequest,
|
||||
) -> Result<GetTransactionsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_alt_blocks_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetAltBlocksHashesRequest,
|
||||
) -> Result<GetAltBlocksHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn is_key_image_spent(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: IsKeyImageSpentRequest,
|
||||
) -> Result<IsKeyImageSpentResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn send_raw_transaction(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SendRawTransactionRequest,
|
||||
) -> Result<SendRawTransactionResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn start_mining(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: StartMiningRequest,
|
||||
) -> Result<StartMiningResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn stop_mining(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: StopMiningRequest,
|
||||
) -> Result<StopMiningResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn mining_status(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: MiningStatusRequest,
|
||||
) -> Result<MiningStatusResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn save_bc(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SaveBcRequest,
|
||||
) -> Result<SaveBcResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_peer_list(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetPeerListRequest,
|
||||
) -> Result<GetPeerListResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_hash_rate(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetLogHashRateRequest,
|
||||
) -> Result<SetLogHashRateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_level(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetLogLevelRequest,
|
||||
) -> Result<SetLogLevelResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_categories(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetLogCategoriesRequest,
|
||||
) -> Result<SetLogCategoriesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_bootstrap_daemon(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetBootstrapDaemonRequest,
|
||||
) -> Result<SetBootstrapDaemonResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionPoolRequest,
|
||||
) -> Result<GetTransactionPoolResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_stats(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionPoolStatsRequest,
|
||||
) -> Result<GetTransactionPoolStatsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn stop_daemon(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: StopDaemonRequest,
|
||||
) -> Result<StopDaemonResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_limit(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetLimitRequest,
|
||||
) -> Result<GetLimitResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_limit(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: SetLimitRequest,
|
||||
) -> Result<SetLimitResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn out_peers(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: OutPeersRequest,
|
||||
) -> Result<OutPeersResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn in_peers(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: InPeersRequest,
|
||||
) -> Result<InPeersResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_net_stats(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetNetStatsRequest,
|
||||
) -> Result<GetNetStatsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_outs(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetOutsRequest,
|
||||
) -> Result<GetOutsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn update(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: UpdateRequest,
|
||||
) -> Result<UpdateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn pop_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: PopBlocksRequest,
|
||||
) -> Result<PopBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetTransactionPoolHashesRequest,
|
||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_public_nodes(
|
||||
state: CupratedRpcHandlerState,
|
||||
request: GetPublicNodesRequest,
|
||||
) -> Result<GetPublicNodesResponse, Error> {
|
||||
todo!()
|
||||
}
|
53
binaries/cuprated/src/statics.rs
Normal file
53
binaries/cuprated/src/statics.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
//! Global `static`s used throughout `cuprated`.
|
||||
|
||||
use std::{
|
||||
sync::{atomic::AtomicU64, LazyLock},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
/// Define all the `static`s that should be always be initialized early on.
|
||||
///
|
||||
/// This wraps all `static`s inside a `LazyLock` and generates
|
||||
/// a [`init_lazylock_statics`] function that must/should be
|
||||
/// used by `main()` early on.
|
||||
macro_rules! define_init_lazylock_statics {
|
||||
($(
|
||||
$( #[$attr:meta] )*
|
||||
$name:ident: $t:ty = $init_fn:expr;
|
||||
)*) => {
|
||||
/// Initialize global static `LazyLock` data.
|
||||
pub fn init_lazylock_statics() {
|
||||
$(
|
||||
LazyLock::force(&$name);
|
||||
)*
|
||||
}
|
||||
|
||||
$(
|
||||
$(#[$attr])*
|
||||
pub static $name: LazyLock<$t> = LazyLock::new(|| $init_fn);
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
define_init_lazylock_statics! {
|
||||
/// The start time of `cuprated`.
|
||||
START_INSTANT: SystemTime = SystemTime::now();
|
||||
|
||||
/// Start time of `cuprated` as a UNIX timestamp.
|
||||
START_INSTANT_UNIX: u64 = START_INSTANT
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Failed to set `cuprated` startup time.")
|
||||
.as_secs();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
/// Sanity check for startup UNIX time.
|
||||
#[test]
|
||||
fn start_instant_unix() {
|
||||
// Fri Sep 27 01:07:13 AM UTC 2024
|
||||
assert!(*START_INSTANT_UNIX > 1727399233);
|
||||
}
|
||||
}
|
3
binaries/cuprated/src/txpool.rs
Normal file
3
binaries/cuprated/src/txpool.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
//! Transaction Pool
|
||||
//!
|
||||
//! Will handle initiating the tx-pool, providing the preprocessor required for the dandelion pool.
|
|
@ -1,4 +1,4 @@
|
|||
## Cuprate's architecture (implementation) book
|
||||
## Cuprate's architecture book
|
||||
This book documents Cuprate's architecture and implementation.
|
||||
|
||||
See:
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
[book]
|
||||
authors = ["hinto-janai"]
|
||||
authors = ["Cuprate Contributors"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "Cuprate Architecture"
|
||||
git-repository-url = "https://github.com/Cuprate/architecture-book"
|
||||
|
||||
# TODO: fix after importing real files.
|
||||
#
|
||||
# [preprocessor.last-changed]
|
||||
# command = "mdbook-last-changed"
|
||||
# renderer = ["html"]
|
||||
#
|
||||
# [output.html]
|
||||
# default-theme = "ayu"
|
||||
# preferred-dark-theme = "ayu"
|
||||
# git-repository-url = "https://github.com/hinto-janai/cuprate-architecture"
|
||||
# additional-css = ["last-changed.css"]
|
||||
[preprocessor.last-changed]
|
||||
command = "mdbook-last-changed"
|
||||
renderer = ["html"]
|
||||
|
||||
[output.html]
|
||||
default-theme = "ayu"
|
||||
preferred-dark-theme = "ayu"
|
||||
git-repository-url = "https://github.com/Cuprate/architecture-book"
|
||||
additional-css = ["last-changed.css"]
|
||||
|
|
7
books/architecture/last-changed.css
Normal file
7
books/architecture/last-changed.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
footer {
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
border-top: 1px solid;
|
||||
margin-top: 4%;
|
||||
padding: 5px 0;
|
||||
}
|
|
@ -1,3 +1,165 @@
|
|||
# Summary
|
||||
|
||||
- [TODO](todo.md)
|
||||
[Cuprate Architecture](cuprate-architecture.md)
|
||||
[🟡 Foreword](foreword.md)
|
||||
|
||||
---
|
||||
|
||||
- [🟠 Intro](intro/intro.md)
|
||||
- [🟡 Who this book is for](intro/who-this-book-is-for.md)
|
||||
- [🔴 Required knowledge](intro/required-knowledge.md)
|
||||
- [🔴 How to use this book](intro/how-to-use-this-book.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Bird's eye view](birds-eye-view/intro.md)
|
||||
- [⚪️ Map](birds-eye-view/map.md)
|
||||
- [⚪️ Components](birds-eye-view/components.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Formats, protocols, types](formats-protocols-types/intro.md)
|
||||
- [⚪️ monero_serai](formats-protocols-types/monero-serai.md)
|
||||
- [⚪️ cuprate_types](formats-protocols-types/cuprate-types.md)
|
||||
- [⚪️ cuprate_helper](formats-protocols-types/cuprate-helper.md)
|
||||
- [⚪️ Epee](formats-protocols-types/epee.md)
|
||||
- [⚪️ Levin](formats-protocols-types/levin.md)
|
||||
|
||||
---
|
||||
|
||||
- [🟢 Storage](storage/intro.md)
|
||||
- [🟢 Database abstraction](storage/db/intro.md)
|
||||
- [🟢 Abstraction](storage/db/abstraction/intro.md)
|
||||
- [🟢 Backend](storage/db/abstraction/backend.md)
|
||||
- [🟢 ConcreteEnv](storage/db/abstraction/concrete_env.md)
|
||||
- [🟢 Trait](storage/db/abstraction/trait.md)
|
||||
- [🟢 Syncing](storage/db/syncing.md)
|
||||
- [🟢 Resizing](storage/db/resizing.md)
|
||||
- [🟢 (De)serialization](storage/db/serde.md)
|
||||
- [🟢 Known issues and tradeoffs](storage/db/issues/intro.md)
|
||||
- [🟢 Abstracting backends](storage/db/issues/traits.md)
|
||||
- [🟢 Hot-swap](storage/db/issues/hot-swap.md)
|
||||
- [🟢 Unaligned bytes](storage/db/issues/unaligned.md)
|
||||
- [🟢 Endianness](storage/db/issues/endian.md)
|
||||
- [🟢 Multimap](storage/db/issues/multimap.md)
|
||||
- [🟢 Common behavior](storage/common/intro.md)
|
||||
- [🟢 Types](storage/common/types.md)
|
||||
- [🟢 `ops`](storage/common/ops.md)
|
||||
- [🟢 `tower::Service`](storage/common/service/intro.md)
|
||||
- [🟢 Initialization](storage/common/service/initialization.md)
|
||||
- [🟢 Requests](storage/common/service/requests.md)
|
||||
- [🟢 Responses](storage/common/service/responses.md)
|
||||
- [🟢 Resizing](storage/common/service/resizing.md)
|
||||
- [🟢 Thread model](storage/common/service/thread-model.md)
|
||||
- [🟢 Shutdown](storage/common/service/shutdown.md)
|
||||
- [🟢 Blockchain](storage/blockchain/intro.md)
|
||||
- [🟢 Schema](storage/blockchain/schema/intro.md)
|
||||
- [🟢 Tables](storage/blockchain/schema/tables.md)
|
||||
- [🟢 Multimap tables](storage/blockchain/schema/multimap.md)
|
||||
- [⚪️ Transaction pool](storage/txpool/intro.md)
|
||||
- [⚪️ Pruning](storage/pruning/intro.md)
|
||||
|
||||
---
|
||||
|
||||
- [🟢 RPC](rpc/intro.md)
|
||||
- [🟡 JSON-RPC 2.0](rpc/json-rpc.md)
|
||||
- [🟢 The types](rpc/types/intro.md)
|
||||
- [🟢 Misc types](rpc/types/misc-types.md)
|
||||
- [🟢 Base RPC types](rpc/types/base-types.md)
|
||||
- [🟢 The type generator macro](rpc/types/macro.md)
|
||||
- [🟢 Metadata](rpc/types/metadata.md)
|
||||
- [🟡 (De)serialization](rpc/types/deserialization.md)
|
||||
- [🟢 The interface](rpc/interface.md)
|
||||
- [🔴 The handler](rpc/handler/intro.md)
|
||||
- [🔴 The server](rpc/server/intro.md)
|
||||
- [🟢 Differences with `monerod`](rpc/differences/intro.md)
|
||||
- [🟢 JSON field ordering](rpc/differences/json-field-ordering.md)
|
||||
- [🟢 JSON formatting](rpc/differences/json-formatting.md)
|
||||
- [🟢 JSON strictness](rpc/differences/json-strictness.md)
|
||||
- [🟡 JSON-RPC strictness](rpc/differences/json-rpc-strictness.md)
|
||||
- [🟡 HTTP methods](rpc/differences/http-methods.md)
|
||||
- [🟡 RPC payment](rpc/differences/rpc-payment.md)
|
||||
- [🟢 Custom strings](rpc/differences/custom-strings.md)
|
||||
- [🔴 Unsupported RPC calls](rpc/differences/unsupported-rpc-calls.md)
|
||||
- [🔴 RPC calls with different behavior](rpc/differences/rpc-calls-with-different-behavior.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ ZMQ](zmq/intro.md)
|
||||
- [⚪️ TODO](zmq/todo.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Consensus](consensus/intro.md)
|
||||
- [⚪️ Verifier](consensus/verifier.md)
|
||||
- [⚪️ TODO](consensus/todo.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Networking](networking/intro.md)
|
||||
- [⚪️ P2P](networking/p2p.md)
|
||||
- [⚪️ Dandelion++](networking/dandelion.md)
|
||||
- [⚪️ Proxy](networking/proxy.md)
|
||||
- [⚪️ Tor](networking/tor.md)
|
||||
- [⚪️ i2p](networking/i2p.md)
|
||||
- [⚪️ IPv4/IPv6](networking/ipv4-ipv6.md)
|
||||
|
||||
---
|
||||
|
||||
- [🔴 Instrumentation](instrumentation/intro.md)
|
||||
- [⚪️ Logging](instrumentation/logging.md)
|
||||
- [⚪️ Data collection](instrumentation/data-collection.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Binary](binary/intro.md)
|
||||
- [⚪️ CLI](binary/cli.md)
|
||||
- [⚪️ Config](binary/config.md)
|
||||
- [⚪️ Logging](binary/logging.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Resources](resources/intro.md)
|
||||
- [⚪️ File system](resources/fs/intro.md)
|
||||
- [🟡 Index of PATHs](resources/fs/paths.md)
|
||||
- [⚪️ Sockets](resources/sockets/index.md)
|
||||
- [🔴 Index of ports](resources/sockets/ports.md)
|
||||
- [⚪️ Memory](resources/memory.md)
|
||||
- [🟡 Concurrency and parallelism](resources/cap/intro.md)
|
||||
- [⚪️ Map](resources/cap/map.md)
|
||||
- [⚪️ The RPC server](resources/cap/the-rpc-server.md)
|
||||
- [⚪️ The database](resources/cap/the-database.md)
|
||||
- [⚪️ The block downloader](resources/cap/the-block-downloader.md)
|
||||
- [⚪️ The verifier](resources/cap/the-verifier.md)
|
||||
- [⚪️ Thread exit](resources/cap/thread-exit.md)
|
||||
- [🔴 Index of threads](resources/cap/threads.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ External Monero libraries](external-monero-libraries/intro.md)
|
||||
- [⚪️ Cryptonight](external-monero-libraries/cryptonight.md)
|
||||
- [🔴 RandomX](external-monero-libraries/randomx.md)
|
||||
- [🔴 monero_serai](external-monero-libraries/monero_serai.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Benchmarking](benchmarking/intro.md)
|
||||
- [⚪️ Criterion](benchmarking/criterion.md)
|
||||
- [⚪️ Harness](benchmarking/harness.md)
|
||||
- [⚪️ Testing](testing/intro.md)
|
||||
- [⚪️ Monero data](testing/monero-data.md)
|
||||
- [⚪️ RPC client](testing/rpc-client.md)
|
||||
- [⚪️ Spawning `monerod`](testing/spawning-monerod.md)
|
||||
- [⚪️ Known issues and tradeoffs](known-issues-and-tradeoffs/intro.md)
|
||||
- [⚪️ Networking](known-issues-and-tradeoffs/networking.md)
|
||||
- [⚪️ RPC](known-issues-and-tradeoffs/rpc.md)
|
||||
- [⚪️ Storage](known-issues-and-tradeoffs/storage.md)
|
||||
|
||||
---
|
||||
|
||||
- [⚪️ Appendix](appendix/intro.md)
|
||||
- [🟢 Crates](appendix/crates.md)
|
||||
- [🔴 Contributing](appendix/contributing.md)
|
||||
- [🔴 Build targets](appendix/build-targets.md)
|
||||
- [🔴 Protocol book](appendix/protocol-book.md)
|
||||
- [⚪️ User book](appendix/user-book.md)
|
7
books/architecture/src/appendix/build-targets.md
Normal file
7
books/architecture/src/appendix/build-targets.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Build targets
|
||||
- x86
|
||||
- ARM64
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
- FreeBSD(?)
|
2
books/architecture/src/appendix/contributing.md
Normal file
2
books/architecture/src/appendix/contributing.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Contributing
|
||||
<https://github.com/Cuprate/cuprate/blob/main/CONTRIBUTING.md>
|
63
books/architecture/src/appendix/crates.md
Normal file
63
books/architecture/src/appendix/crates.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Crates
|
||||
This is an index of all of Cuprate's in-house crates it uses and maintains.
|
||||
|
||||
They are categorized into groups.
|
||||
|
||||
Crate documentation for each crate can be found by clicking the crate name or by visiting <https://doc.cuprate.org>. Documentation can also be built manually by running this at the root of the `cuprate` repository:
|
||||
```bash
|
||||
cargo doc --package $CRATE
|
||||
```
|
||||
For example, this will generate and open `cuprate-blockchain` documentation:
|
||||
```bash
|
||||
cargo doc --open --package cuprate-blockchain
|
||||
```
|
||||
|
||||
## Consensus
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-consensus`](https://doc.cuprate.org/cuprate_consensus) | [`consensus/`](https://github.com/Cuprate/cuprate/tree/main/consensus) | TODO
|
||||
| [`cuprate-consensus-rules`](https://doc.cuprate.org/cuprate_consensus_rules) | [`consensus/rules/`](https://github.com/Cuprate/cuprate/tree/main/consensus-rules) | TODO
|
||||
| [`cuprate-fast-sync`](https://doc.cuprate.org/cuprate_fast_sync) | [`consensus/fast-sync/`](https://github.com/Cuprate/cuprate/tree/main/consensus/fast-sync) | Fast block synchronization
|
||||
|
||||
## Networking
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-epee-encoding`](https://doc.cuprate.org/cuprate_epee_encoding) | [`net/epee-encoding/`](https://github.com/Cuprate/cuprate/tree/main/net/epee-encoding) | Epee (de)serialization
|
||||
| [`cuprate-fixed-bytes`](https://doc.cuprate.org/cuprate_fixed_bytes) | [`net/fixed-bytes/`](https://github.com/Cuprate/cuprate/tree/main/net/fixed-bytes) | Fixed byte containers backed by `byte::Byte`
|
||||
| [`cuprate-levin`](https://doc.cuprate.org/cuprate_levin) | [`net/levin/`](https://github.com/Cuprate/cuprate/tree/main/net/levin) | Levin bucket protocol implementation
|
||||
| [`cuprate-wire`](https://doc.cuprate.org/cuprate_wire) | [`net/wire/`](https://github.com/Cuprate/cuprate/tree/main/net/wire) | TODO
|
||||
|
||||
## P2P
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-address-book`](https://doc.cuprate.org/cuprate_address_book) | [`p2p/address-book/`](https://github.com/Cuprate/cuprate/tree/main/p2p/address-book) | TODO
|
||||
| [`cuprate-async-buffer`](https://doc.cuprate.org/cuprate_async_buffer) | [`p2p/async-buffer/`](https://github.com/Cuprate/cuprate/tree/main/p2p/async-buffer) | A bounded SPSC, FIFO, asynchronous buffer that supports arbitrary weights for values
|
||||
| [`cuprate-dandelion-tower`](https://doc.cuprate.org/cuprate_dandelion_tower) | [`p2p/dandelion-tower/`](https://github.com/Cuprate/cuprate/tree/main/p2p/dandelion-tower) | TODO
|
||||
| [`cuprate-p2p`](https://doc.cuprate.org/cuprate_p2p) | [`p2p/p2p/`](https://github.com/Cuprate/cuprate/tree/main/p2p/p2p) | TODO
|
||||
| [`cuprate-p2p-core`](https://doc.cuprate.org/cuprate_p2p_core) | [`p2p/p2p-core/`](https://github.com/Cuprate/cuprate/tree/main/p2p/p2p-core) | TODO
|
||||
|
||||
## Storage
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-blockchain`](https://doc.cuprate.org/cuprate_blockchain) | [`storage/blockchain/`](https://github.com/Cuprate/cuprate/tree/main/storage/blockchain) | Blockchain database built on-top of `cuprate-database` & `cuprate-database-service`
|
||||
| [`cuprate-database`](https://doc.cuprate.org/cuprate_database) | [`storage/database/`](https://github.com/Cuprate/cuprate/tree/main/storage/database) | Pure database abstraction
|
||||
| [`cuprate-database-service`](https://doc.cuprate.org/cuprate_database_service) | [`storage/database-service/`](https://github.com/Cuprate/cuprate/tree/main/storage/database-service) | `tower::Service` + thread-pool abstraction built on-top of `cuprate-database`
|
||||
| [`cuprate-txpool`](https://doc.cuprate.org/cuprate_txpool) | [`storage/txpool/`](https://github.com/Cuprate/cuprate/tree/main/storage/txpool) | Transaction pool database built on-top of `cuprate-database` & `cuprate-database-service`
|
||||
|
||||
## RPC
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-json-rpc`](https://doc.cuprate.org/cuprate_json_rpc) | [`rpc/json-rpc/`](https://github.com/Cuprate/cuprate/tree/main/rpc/json-rpc) | JSON-RPC 2.0 implementation
|
||||
| [`cuprate-rpc-types`](https://doc.cuprate.org/cuprate_rpc_types) | [`rpc/types/`](https://github.com/Cuprate/cuprate/tree/main/rpc/types) | Monero RPC types and traits
|
||||
| [`cuprate-rpc-interface`](https://doc.cuprate.org/cuprate_rpc_interface) | [`rpc/interface/`](https://github.com/Cuprate/cuprate/tree/main/rpc/interface) | RPC interface & routing
|
||||
| [`cuprate-rpc-handler`](https://doc.cuprate.org/cuprate_rpc_handler) | [`rpc/handler/`](https://github.com/Cuprate/cuprate/tree/main/rpc/handler) | RPC inner handlers
|
||||
|
||||
## 1-off crates
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-constants`](https://doc.cuprate.org/cuprate_constants) | [`constants/`](https://github.com/Cuprate/cuprate/tree/main/constants) | Shared `const/static` data across Cuprate
|
||||
| [`cuprate-cryptonight`](https://doc.cuprate.org/cuprate_cryptonight) | [`cryptonight/`](https://github.com/Cuprate/cuprate/tree/main/cryptonight) | CryptoNight hash functions
|
||||
| [`cuprate-pruning`](https://doc.cuprate.org/cuprate_pruning) | [`pruning/`](https://github.com/Cuprate/cuprate/tree/main/pruning) | Monero pruning logic/types
|
||||
| [`cuprate-helper`](https://doc.cuprate.org/cuprate_helper) | [`helper/`](https://github.com/Cuprate/cuprate/tree/main/helper) | Kitchen-sink helper crate for Cuprate
|
||||
| [`cuprate-test-utils`](https://doc.cuprate.org/cuprate_test_utils) | [`test-utils/`](https://github.com/Cuprate/cuprate/tree/main/test-utils) | Testing utilities for Cuprate
|
||||
| [`cuprate-types`](https://doc.cuprate.org/cuprate_types) | [`types/`](https://github.com/Cuprate/cuprate/tree/main/types) | Shared types across Cuprate
|
1
books/architecture/src/appendix/intro.md
Normal file
1
books/architecture/src/appendix/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Appendix
|
2
books/architecture/src/appendix/protocol-book.md
Normal file
2
books/architecture/src/appendix/protocol-book.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Protocol book
|
||||
<https://monero-book.cuprate.org>
|
1
books/architecture/src/appendix/user-book.md
Normal file
1
books/architecture/src/appendix/user-book.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ User book
|
1
books/architecture/src/benchmarking/criterion.md
Normal file
1
books/architecture/src/benchmarking/criterion.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Criterion
|
1
books/architecture/src/benchmarking/harness.md
Normal file
1
books/architecture/src/benchmarking/harness.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Harness
|
1
books/architecture/src/benchmarking/intro.md
Normal file
1
books/architecture/src/benchmarking/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Benchmarking
|
1
books/architecture/src/binary/cli.md
Normal file
1
books/architecture/src/binary/cli.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ CLI
|
1
books/architecture/src/binary/config.md
Normal file
1
books/architecture/src/binary/config.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Config
|
1
books/architecture/src/binary/intro.md
Normal file
1
books/architecture/src/binary/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Binary
|
1
books/architecture/src/binary/logging.md
Normal file
1
books/architecture/src/binary/logging.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Logging
|
1
books/architecture/src/birds-eye-view/components.md
Normal file
1
books/architecture/src/birds-eye-view/components.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Components
|
1
books/architecture/src/birds-eye-view/intro.md
Normal file
1
books/architecture/src/birds-eye-view/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Bird's eye view
|
1
books/architecture/src/birds-eye-view/map.md
Normal file
1
books/architecture/src/birds-eye-view/map.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Map
|
1
books/architecture/src/consensus/intro.md
Normal file
1
books/architecture/src/consensus/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Consensus
|
1
books/architecture/src/consensus/todo.md
Normal file
1
books/architecture/src/consensus/todo.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ TODO
|
1
books/architecture/src/consensus/verifier.md
Normal file
1
books/architecture/src/consensus/verifier.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Verifier
|
22
books/architecture/src/cuprate-architecture.md
Normal file
22
books/architecture/src/cuprate-architecture.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Cuprate Architecture
|
||||
WIP
|
||||
|
||||
[Cuprate](https://github.com/Cuprate/cuprate)'s architecture book.
|
||||
|
||||
Sections are notated with colors indicating how complete they are:
|
||||
|
||||
| Color | Meaning |
|
||||
|-------|---------|
|
||||
| ⚪️ | Empty
|
||||
| 🔴 | Severely lacking information
|
||||
| 🟠 | Lacking some information
|
||||
| 🟡 | Almost ready
|
||||
| 🟢 | OK
|
||||
|
||||
---
|
||||
|
||||
Continue to the next chapter by clicking the right `>` button, or by selecting it on the left side.
|
||||
|
||||
All chapters are viewable by clicking the top-left `☰` button.
|
||||
|
||||
The entire book can searched by clicking the top-left 🔍 button.
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ Cryptonight
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ External Monero libraries
|
|
@ -0,0 +1,2 @@
|
|||
# monero_serai
|
||||
<https://github.com/serai-dex/serai/tree/develop/coins/monero>
|
|
@ -0,0 +1,2 @@
|
|||
# RandomX
|
||||
<https://github.com/tari-project/randomx-rs>
|
36
books/architecture/src/foreword.md
Normal file
36
books/architecture/src/foreword.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Foreword
|
||||
Monero[^1] is a large software project, coming in at 329k lines of C++, C, headers, and make files.[^2] It is directly responsible for 2.6 billion dollars worth of value.[^3] It has had over 400 contributors, more if counting unnamed contributions.[^4] It has over 10,000 node operators and a large active userbase.[^5]
|
||||
|
||||
The project wasn't always this big, but somewhere in the midst of contributors coming and going, various features being added, bugs being fixed, and celebrated cryptography being implemented - there was an aspect that was lost by the project that it could not easily gain again: **maintainability**.
|
||||
|
||||
Within large and complicated software projects, there is an important transfer of knowledge that must occur for long-term survival. Much like an organism that must eventually pass the torch onto the next generation, projects must do the same for future contributors.
|
||||
|
||||
However, newcomers often lack experience, past contributors might not be around, and current maintainers may be too busy. For whatever reason, this transfer of knowledge is not always smooth.
|
||||
|
||||
There is a solution to this problem: **documentation**.
|
||||
|
||||
The activity of writing the what, where, why, and how of the solutions to technical problems can be done in an author's lonesome.
|
||||
|
||||
The activity of reading these ideas can be done by future readers at any time without permission.
|
||||
|
||||
These readers may be new prospective contributors, it may be the current maintainers, it may be researchers, it may be users of various scale. Whoever it may be, documentation acts as the link between the past and present; a bottle of wisdom thrown into the river of time for future participants to open.
|
||||
|
||||
This book is the manifestation of this will, for Cuprate[^6], an alternative Monero node. It documents Cuprate's implementation from head-to-toe such that in the case of a contributor's untimely disappearance, the project can continue.
|
||||
|
||||
People come and go, documentation is forever.
|
||||
|
||||
— hinto-janai
|
||||
|
||||
---
|
||||
|
||||
[^1]: [`monero-project/monero`](https://github.com/monero-project/monero)
|
||||
|
||||
[^2]: `git ls-files | grep "\.cpp$\|\.h$\|\.c$\|CMake" | xargs cat | wc -l` on [`cc73fe7`](https://github.com/monero-project/monero/tree/cc73fe71162d564ffda8e549b79a350bca53c454)
|
||||
|
||||
[^3]: 2024-05-24: $143.55 USD * 18,151,608 XMR = $2,605,663,258
|
||||
|
||||
[^4]: `git log --all --pretty="%an" | sort -u | wc -l` on [`cc73fe7`](https://github.com/monero-project/monero/tree/cc73fe71162d564ffda8e549b79a350bca53c454)
|
||||
|
||||
[^5]: <https://monero.fail/map>
|
||||
|
||||
[^6]: <https://github.com/Cuprate/cuprate>
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ cuprate_helper
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ cuprate_types
|
1
books/architecture/src/formats-protocols-types/epee.md
Normal file
1
books/architecture/src/formats-protocols-types/epee.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Epee
|
1
books/architecture/src/formats-protocols-types/intro.md
Normal file
1
books/architecture/src/formats-protocols-types/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Formats, protocols, types
|
1
books/architecture/src/formats-protocols-types/levin.md
Normal file
1
books/architecture/src/formats-protocols-types/levin.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Levin
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ monero_serai
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ Data collection
|
2
books/architecture/src/instrumentation/intro.md
Normal file
2
books/architecture/src/instrumentation/intro.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Instrumentation
|
||||
Cuprate is built with [instrumentation](https://en.wikipedia.org/wiki/Instrumentation) in mind.
|
1
books/architecture/src/instrumentation/logging.md
Normal file
1
books/architecture/src/instrumentation/logging.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Logging
|
5
books/architecture/src/intro/how-to-use-this-book.md
Normal file
5
books/architecture/src/intro/how-to-use-this-book.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# How to use this book
|
||||
|
||||
## Maintainers
|
||||
## Contributors
|
||||
## Researchers
|
15
books/architecture/src/intro/intro.md
Normal file
15
books/architecture/src/intro/intro.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Intro
|
||||
[Cuprate](https://github.com/Cuprate/cuprate) is an alternative [Monero](https://getmonero.org) node implementation.
|
||||
|
||||
This book describes Cuprate's architecture, ranging from small things like database pruning to larger meta-components like the networking stack.
|
||||
|
||||
A brief overview of some aspects covered within this book:
|
||||
- Component designs
|
||||
- Implementation details
|
||||
- File location and purpose
|
||||
- Design decisions and tradeoffs
|
||||
- Things in relation to `monerod`
|
||||
- Dependency usage
|
||||
|
||||
## Source code
|
||||
The source files for this book can be found on at: <https://github.com/Cuprate/architecture-book>.
|
28
books/architecture/src/intro/required-knowledge.md
Normal file
28
books/architecture/src/intro/required-knowledge.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Required knowledge
|
||||
|
||||
## General
|
||||
- Rust
|
||||
- Monero
|
||||
- System design
|
||||
|
||||
## Components
|
||||
### Storage
|
||||
- Embedded databases
|
||||
- LMDB
|
||||
- redb
|
||||
|
||||
### RPC
|
||||
- `axum`
|
||||
- `tower`
|
||||
- `async`
|
||||
- JSON-RPC 2.0
|
||||
- Epee
|
||||
|
||||
### Networking
|
||||
- `tower`
|
||||
- `tokio`
|
||||
- `async`
|
||||
- Levin
|
||||
|
||||
### Instrumentation
|
||||
- `tracing`
|
31
books/architecture/src/intro/who-this-book-is-for.md
Normal file
31
books/architecture/src/intro/who-this-book-is-for.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Who this book is for
|
||||
|
||||
## Maintainers
|
||||
As mentioned in [`Foreword`](../foreword.md), the group of people that benefit from this book's value the most by far are the current and future Cuprate maintainers.
|
||||
|
||||
Cuprate's system design is documented in this book such that if you were ever to build it again from scratch, you would have an excellent guide on how to do such, and also where improvements could be made.
|
||||
|
||||
Practically, what that means for maintainers is that it acts as _the_ reference. During maintenance, it is quite valuable to have a book that contains condensed knowledge on the behavior of components, or how certain code works, or why it was built a certain way.
|
||||
|
||||
## Contributors
|
||||
Contributors also have access to the inner-workings of Cuprate via this book, which helps when making larger contributions.
|
||||
|
||||
Design decisions and implementation details notated in this book helps answer questions such as:
|
||||
- Why is it done this way?
|
||||
- Why can it _not_ be done this way?
|
||||
- Were other methods attempted?
|
||||
|
||||
Cuprate's testing and benchmarking suites, unknown to new contributors, are also documented within this book.
|
||||
|
||||
## Researchers
|
||||
This book contains the why, where, and how of the _implementation_ of formal research.
|
||||
|
||||
Although it is an informal specification, this book still acts as a more accessible overview of Cuprate compared to examining the codebase itself.
|
||||
|
||||
## Operators & users
|
||||
This book is not a practical guide for using Cuprate itself.
|
||||
|
||||
For configuration, data collection (also important for researchers), and other practical usage, see [Cuprate's user book](https://user.cuprate.org).
|
||||
|
||||
## Observers
|
||||
Anyone curious enough is free to learn the inner-workings of Cuprate via this book, and maybe even contribute someday.
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ Known issues and tradeoffs
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ Networking
|
1
books/architecture/src/known-issues-and-tradeoffs/rpc.md
Normal file
1
books/architecture/src/known-issues-and-tradeoffs/rpc.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ RPC
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ Storage
|
1
books/architecture/src/networking/dandelion.md
Normal file
1
books/architecture/src/networking/dandelion.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Dandelion++
|
1
books/architecture/src/networking/i2p.md
Normal file
1
books/architecture/src/networking/i2p.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ i2p
|
1
books/architecture/src/networking/intro.md
Normal file
1
books/architecture/src/networking/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Networking
|
1
books/architecture/src/networking/ipv4-ipv6.md
Normal file
1
books/architecture/src/networking/ipv4-ipv6.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ IPv4/IPv6
|
1
books/architecture/src/networking/p2p.md
Normal file
1
books/architecture/src/networking/p2p.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ P2P
|
1
books/architecture/src/networking/proxy.md
Normal file
1
books/architecture/src/networking/proxy.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Proxy
|
1
books/architecture/src/networking/tor.md
Normal file
1
books/architecture/src/networking/tor.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Tor
|
32
books/architecture/src/resources/cap/intro.md
Normal file
32
books/architecture/src/resources/cap/intro.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Concurrency and parallelism
|
||||
It is incumbent upon software like Cuprate to take advantage of today's highly parallel hardware as much as practically possible.
|
||||
|
||||
With that said, programs must setup guardrails when operating in a concurrent and parallel manner, [for correctness and safety](https://en.wikipedia.org/wiki/Concurrency_(computer_science)).
|
||||
|
||||
There are "synchronization primitives" that help with this, common ones being:
|
||||
- [Locks](https://en.wikipedia.org/wiki/Lock_(computer_science))
|
||||
- [Channels](https://en.wikipedia.org/wiki/Channel_(programming))
|
||||
- [Atomics](https://en.wikipedia.org/wiki/Linearizability#Primitive_atomic_instructions)
|
||||
|
||||
These tools are relatively easy to use in isolation, but trickier to do so when considering the entire system. It is not uncommon for _the_ bottleneck to be the [poor orchastration](https://en.wikipedia.org/wiki/Starvation_(computer_science)) of these primitives.
|
||||
|
||||
## Analogy
|
||||
A common analogy for a parallel system is an intersection.
|
||||
|
||||
Like a parallel computer system, an intersection contains:
|
||||
1. **Parallelism:** multiple individual units that want to move around (cars, pedestrians, etc)
|
||||
1. **Synchronization primitives:** traffic lights, car lights, walk signals
|
||||
|
||||
In theory, the amount of "work" the units can do is only limited by the speed of the units themselves, but in practice, the slow cascading reaction speeds between all units, the frequent hiccups that can occur, and the synchronization primitives themselves become bottlenecks far before the maximum speed of any unit is reached.
|
||||
|
||||
A car that hogs the middle of the intersection on the wrong light is akin to a system thread holding onto a lock longer than it should be - it degrades total system output.
|
||||
|
||||
Unlike humans however, computer systems at least have the potential to move at lightning speeds, but only if the above synchronization primitives are used correctly.
|
||||
|
||||
## Goal
|
||||
To aid the long-term maintenance of highly concurrent and parallel code, this section documents:
|
||||
1. All system threads spawned and maintained
|
||||
1. All major sections where synchronization primitives are used
|
||||
1. The asynchronous behavior of some components
|
||||
|
||||
and how these compose together efficiently in Cuprate.
|
1
books/architecture/src/resources/cap/map.md
Normal file
1
books/architecture/src/resources/cap/map.md
Normal file
|
@ -0,0 +1 @@
|
|||
# ⚪️ Map
|
|
@ -0,0 +1 @@
|
|||
# ⚪️ The block downloader
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue