mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-17 00:07:55 +00:00
move consensus database to /types
This commit is contained in:
parent
889e15738b
commit
ee9bc70f8e
24 changed files with 352 additions and 784 deletions
366
Cargo.lock
generated
366
Cargo.lock
generated
|
@ -29,12 +29,6 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
|
@ -115,15 +109,6 @@ version = "1.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
|
@ -150,10 +135,6 @@ name = "bitflags"
|
|||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
|
@ -215,26 +196,6 @@ version = "3.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
@ -316,19 +277,6 @@ name = "crossbeam"
|
|||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
@ -352,15 +300,6 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
|
@ -401,39 +340,6 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuprate-blockchain"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bytemuck",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"crossbeam",
|
||||
"cuprate-helper",
|
||||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
"curve25519-dalek",
|
||||
"futures",
|
||||
"heed",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-pruning",
|
||||
"monero-serai",
|
||||
"page_size",
|
||||
"paste",
|
||||
"pretty_assertions",
|
||||
"rayon",
|
||||
"redb",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"thread_local",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuprate-consensus"
|
||||
version = "0.1.0"
|
||||
|
@ -441,6 +347,7 @@ dependencies = [
|
|||
"cuprate-consensus-rules",
|
||||
"cuprate-helper",
|
||||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"futures",
|
||||
|
@ -508,7 +415,7 @@ dependencies = [
|
|||
"fixed-bytes",
|
||||
"futures",
|
||||
"hex",
|
||||
"indexmap 2.2.6",
|
||||
"indexmap",
|
||||
"monero-address-book",
|
||||
"monero-p2p",
|
||||
"monero-pruning",
|
||||
|
@ -557,11 +464,8 @@ version = "0.0.0"
|
|||
name = "cuprate-types"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"cfg-if",
|
||||
"curve25519-dalek",
|
||||
"monero-serai",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -632,7 +536,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
|
@ -693,15 +597,6 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doxygen-rs"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9"
|
||||
dependencies = [
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.11.0"
|
||||
|
@ -808,15 +703,6 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
|
@ -938,12 +824,6 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
|
@ -951,17 +831,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hdrhistogram"
|
||||
version = "7.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -970,44 +839,6 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heed"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7a300b0deeb2957162d7752b0f063b3be1c88333af5bb4e7a57d8fb3716f50b"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"heed-traits",
|
||||
"heed-types",
|
||||
"libc",
|
||||
"lmdb-master-sys",
|
||||
"once_cell",
|
||||
"page_size",
|
||||
"serde",
|
||||
"synchronoise",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heed-traits"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff"
|
||||
|
||||
[[package]]
|
||||
name = "heed-types"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cb0d6ba3700c9a57e83c013693e3eddb68a6d9b6781cacafc62a0d992e8ddb3"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder",
|
||||
"heed-traits",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
|
@ -1155,26 +986,6 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
|
@ -1182,7 +993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1258,17 +1069,6 @@ version = "0.4.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-master-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc9048db3a58c0732d7236abc4909058f9d2708cfb6d7d047eb895fddec6419a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"doxygen-rs",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
|
@ -1340,7 +1140,7 @@ dependencies = [
|
|||
"borsh",
|
||||
"cuprate-test-utils",
|
||||
"futures",
|
||||
"indexmap 2.2.6",
|
||||
"indexmap",
|
||||
"monero-p2p",
|
||||
"monero-pruning",
|
||||
"monero-wire",
|
||||
|
@ -1500,16 +1300,6 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "page_size"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.0"
|
||||
|
@ -1568,54 +1358,6 @@ dependencies = [
|
|||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.5"
|
||||
|
@ -1842,15 +1584,6 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redb"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed7508e692a49b6b2290b56540384ccae9b1fb4d77065640b165835b56ffe3bb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
|
@ -2148,12 +1881,6 @@ dependencies = [
|
|||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
|
@ -2190,7 +1917,7 @@ name = "std-shims"
|
|||
version = "0.1.1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
"spin",
|
||||
]
|
||||
|
||||
|
@ -2234,15 +1961,6 @@ dependencies = [
|
|||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synchronoise"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2"
|
||||
dependencies = [
|
||||
"crossbeam-queue",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
|
@ -2300,21 +2018,6 @@ dependencies = [
|
|||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
|
@ -2376,10 +2079,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hashbrown 0.14.5",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
"tokio",
|
||||
|
@ -2398,7 +2098,7 @@ version = "0.21.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
@ -2411,12 +2111,8 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
|||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"hdrhistogram",
|
||||
"indexmap 1.9.3",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
|
@ -2495,44 +2191,18 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -2617,28 +2287,6 @@ version = "0.2.92"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.56.0"
|
||||
|
|
|
@ -14,7 +14,7 @@ members = [
|
|||
"p2p/dandelion",
|
||||
"p2p/monero-p2p",
|
||||
"p2p/address-book",
|
||||
"storage/cuprate-blockchain",
|
||||
#"storage/cuprate-blockchain",
|
||||
"storage/cuprate-txpool",
|
||||
"storage/database",
|
||||
"pruning",
|
||||
|
|
|
@ -10,6 +10,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/consensus"
|
|||
[dependencies]
|
||||
cuprate-helper = { path = "../helper", default-features = false, features = ["std", "asynch", "num"] }
|
||||
cuprate-consensus-rules = { path = "./rules", features = ["rayon"] }
|
||||
cuprate-types = { path = "../types" }
|
||||
|
||||
thiserror = { workspace = true }
|
||||
tower = { workspace = true, features = ["util"] }
|
||||
|
|
|
@ -163,6 +163,7 @@ impl HardFork {
|
|||
/// Returns the hard-fork for a blocks `major_version` field.
|
||||
///
|
||||
/// <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
||||
#[inline]
|
||||
pub fn from_version(version: u8) -> Result<HardFork, HardForkError> {
|
||||
Ok(match version {
|
||||
1 => HardFork::V1,
|
||||
|
@ -188,6 +189,7 @@ impl HardFork {
|
|||
/// Returns the hard-fork for a blocks `minor_version` (vote) field.
|
||||
///
|
||||
/// <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
||||
#[inline]
|
||||
pub fn from_vote(vote: u8) -> HardFork {
|
||||
if vote == 0 {
|
||||
// A vote of 0 is interpreted as 1 as that's what Monero used to default to.
|
||||
|
@ -197,6 +199,7 @@ impl HardFork {
|
|||
Self::from_version(vote).unwrap_or(HardFork::V16)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_block_header(header: &BlockHeader) -> Result<(HardFork, HardFork), HardForkError> {
|
||||
Ok((
|
||||
HardFork::from_version(header.major_version)?,
|
||||
|
|
|
@ -6,22 +6,13 @@ use std::{
|
|||
use curve25519_dalek::EdwardsPoint;
|
||||
use monero_serai::transaction::{Input, Timelock};
|
||||
|
||||
use crate::{transactions::TransactionError, HardFork, TxVersion};
|
||||
|
||||
/// An already approved previous transaction output.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct OutputOnChain {
|
||||
pub height: u64,
|
||||
pub time_lock: Timelock,
|
||||
pub key: Option<EdwardsPoint>,
|
||||
pub commitment: EdwardsPoint,
|
||||
}
|
||||
use crate::{transactions::TransactionError, HardFork};
|
||||
|
||||
/// Gets the absolute offsets from the relative offsets.
|
||||
///
|
||||
/// This function will return an error if the relative offsets are empty.
|
||||
/// <https://cuprate.github.io/monero-book/consensus_rules/transactions.html#inputs-must-have-decoys>
|
||||
fn get_absolute_offsets(relative_offsets: &[u64]) -> Result<Vec<u64>, TransactionError> {
|
||||
pub fn get_absolute_offsets(relative_offsets: &[u64]) -> Result<Vec<u64>, TransactionError> {
|
||||
if relative_offsets.is_empty() {
|
||||
return Err(TransactionError::InputDoesNotHaveExpectedNumbDecoys);
|
||||
}
|
||||
|
@ -64,35 +55,6 @@ pub fn insert_ring_member_ids(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the ring members for the inputs from the outputs on the chain.
|
||||
///
|
||||
/// Will error if `outputs` does not contain the outputs needed.
|
||||
pub fn get_ring_members_for_inputs(
|
||||
get_outputs: impl Fn(u64, u64) -> Option<OutputOnChain>,
|
||||
inputs: &[Input],
|
||||
) -> Result<Vec<Vec<OutputOnChain>>, TransactionError> {
|
||||
inputs
|
||||
.iter()
|
||||
.map(|inp| match inp {
|
||||
Input::ToKey {
|
||||
amount,
|
||||
key_offsets,
|
||||
..
|
||||
} => {
|
||||
let offsets = get_absolute_offsets(key_offsets)?;
|
||||
Ok(offsets
|
||||
.iter()
|
||||
.map(|offset| {
|
||||
get_outputs(amount.unwrap_or(0), *offset)
|
||||
.ok_or(TransactionError::RingMemberNotFoundOrInvalid)
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()?)
|
||||
}
|
||||
_ => Err(TransactionError::IncorrectInputType),
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()
|
||||
}
|
||||
|
||||
/// Represents the ring members of all the inputs.
|
||||
#[derive(Debug)]
|
||||
pub enum Rings {
|
||||
|
@ -102,45 +64,6 @@ pub enum Rings {
|
|||
RingCT(Vec<Vec<[EdwardsPoint; 2]>>),
|
||||
}
|
||||
|
||||
impl Rings {
|
||||
/// Builds the rings for the transaction inputs, from the given outputs.
|
||||
fn new(
|
||||
outputs: Vec<Vec<OutputOnChain>>,
|
||||
tx_version: TxVersion,
|
||||
) -> Result<Rings, TransactionError> {
|
||||
Ok(match tx_version {
|
||||
TxVersion::RingSignatures => Rings::Legacy(
|
||||
outputs
|
||||
.into_iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.into_iter()
|
||||
.map(|out| out.key.ok_or(TransactionError::RingMemberNotFoundOrInvalid))
|
||||
.collect::<Result<Vec<_>, TransactionError>>()
|
||||
})
|
||||
.collect::<Result<Vec<_>, TransactionError>>()?,
|
||||
),
|
||||
TxVersion::RingCT => Rings::RingCT(
|
||||
outputs
|
||||
.into_iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.into_iter()
|
||||
.map(|out| {
|
||||
Ok([
|
||||
out.key
|
||||
.ok_or(TransactionError::RingMemberNotFoundOrInvalid)?,
|
||||
out.commitment,
|
||||
])
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Information on the outputs the transaction is referencing for inputs (ring members).
|
||||
#[derive(Debug)]
|
||||
pub struct TxRingMembersInfo {
|
||||
|
@ -151,46 +74,6 @@ pub struct TxRingMembersInfo {
|
|||
pub time_locked_outs: Vec<Timelock>,
|
||||
}
|
||||
|
||||
impl TxRingMembersInfo {
|
||||
/// Construct a [`TxRingMembersInfo`] struct.
|
||||
///
|
||||
/// The used outs must be all the ring members used in the transactions inputs.
|
||||
pub fn new(
|
||||
used_outs: Vec<Vec<OutputOnChain>>,
|
||||
decoy_info: Option<DecoyInfo>,
|
||||
tx_version: TxVersion,
|
||||
) -> Result<TxRingMembersInfo, TransactionError> {
|
||||
Ok(TxRingMembersInfo {
|
||||
youngest_used_out_height: used_outs
|
||||
.iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.iter()
|
||||
// the output with the highest height is the youngest
|
||||
.map(|out| out.height)
|
||||
.max()
|
||||
.expect("Input must have ring members")
|
||||
})
|
||||
.max()
|
||||
.expect("Tx must have inputs"),
|
||||
time_locked_outs: used_outs
|
||||
.iter()
|
||||
.flat_map(|inp_outs| {
|
||||
inp_outs
|
||||
.iter()
|
||||
.filter_map(|out| match out.time_lock {
|
||||
Timelock::None => None,
|
||||
lock => Some(lock),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect(),
|
||||
rings: Rings::new(used_outs, tx_version)?,
|
||||
decoy_info,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct holding information about the inputs and their decoys. This data can vary by block so
|
||||
/// this data needs to be retrieved after every change in the blockchain.
|
||||
///
|
||||
|
|
|
@ -12,8 +12,9 @@ use tower::ServiceExt;
|
|||
use tracing::instrument;
|
||||
|
||||
use cuprate_helper::num::median;
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork};
|
||||
use crate::{Database, ExtendedConsensusError, HardFork};
|
||||
|
||||
/// The amount of blocks we account for to calculate difficulty
|
||||
const DIFFICULTY_WINDOW: usize = 720;
|
||||
|
@ -301,8 +302,8 @@ async fn get_blocks_in_pow_info<D: Database + Clone>(
|
|||
) -> Result<(VecDeque<u64>, VecDeque<u128>), ExtendedConsensusError> {
|
||||
tracing::info!("Getting blocks timestamps");
|
||||
|
||||
let DatabaseResponse::BlockExtendedHeaderInRange(ext_header) = database
|
||||
.oneshot(DatabaseRequest::BlockExtendedHeaderInRange(block_heights))
|
||||
let BCResponse::BlockExtendedHeaderInRange(ext_header) = database
|
||||
.oneshot(BCReadRequest::BlockExtendedHeaderInRange(block_heights))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response");
|
||||
|
|
|
@ -4,8 +4,9 @@ use tower::ServiceExt;
|
|||
use tracing::instrument;
|
||||
|
||||
use cuprate_consensus_rules::{HFVotes, HFsInfo, HardFork};
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError};
|
||||
use crate::{Database, ExtendedConsensusError};
|
||||
|
||||
/// The default amount of hard-fork votes to track to decide on activation of a hard-fork.
|
||||
///
|
||||
|
@ -86,16 +87,17 @@ impl HardForkState {
|
|||
debug_assert_eq!(votes.total_votes(), config.window)
|
||||
}
|
||||
|
||||
let DatabaseResponse::BlockExtendedHeader(ext_header) = database
|
||||
let BCResponse::BlockExtendedHeader(ext_header) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::BlockExtendedHeader(chain_height - 1))
|
||||
.call(BCReadRequest::BlockExtendedHeader(chain_height - 1))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
};
|
||||
|
||||
let current_hardfork = ext_header.version;
|
||||
let current_hardfork =
|
||||
HardFork::from_version(ext_header.version).expect("Stored block has invalid hardfork");
|
||||
|
||||
let mut hfs = HardForkState {
|
||||
config,
|
||||
|
@ -165,15 +167,15 @@ async fn get_votes_in_range<D: Database>(
|
|||
) -> Result<HFVotes, ExtendedConsensusError> {
|
||||
let mut votes = HFVotes::new(window_size);
|
||||
|
||||
let DatabaseResponse::BlockExtendedHeaderInRange(vote_list) = database
|
||||
.oneshot(DatabaseRequest::BlockExtendedHeaderInRange(block_heights))
|
||||
let BCResponse::BlockExtendedHeaderInRange(vote_list) = database
|
||||
.oneshot(BCReadRequest::BlockExtendedHeaderInRange(block_heights))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
};
|
||||
|
||||
for hf_info in vote_list.into_iter() {
|
||||
votes.add_vote_for_hf(&hf_info.vote);
|
||||
votes.add_vote_for_hf(&HardFork::from_vote(hf_info.vote));
|
||||
}
|
||||
|
||||
Ok(votes)
|
||||
|
|
|
@ -20,8 +20,9 @@ use cuprate_consensus_rules::{
|
|||
HardFork,
|
||||
};
|
||||
use cuprate_helper::asynch::rayon_spawn_async;
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError};
|
||||
use crate::{Database, ExtendedConsensusError};
|
||||
|
||||
/// The amount of randomX VMs to keep in the cache.
|
||||
const RX_SEEDS_CACHED: usize = 2;
|
||||
|
@ -225,10 +226,8 @@ async fn get_block_hashes<D: Database + Clone>(
|
|||
for height in heights {
|
||||
let db = database.clone();
|
||||
fut.push_back(async move {
|
||||
let DatabaseResponse::BlockHash(hash) = db
|
||||
.clone()
|
||||
.oneshot(DatabaseRequest::BlockHash(height))
|
||||
.await?
|
||||
let BCResponse::BlockHash(hash) =
|
||||
db.clone().oneshot(BCReadRequest::BlockHash(height)).await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
};
|
||||
|
|
|
@ -9,13 +9,14 @@ use tower::ServiceExt;
|
|||
use tracing::Instrument;
|
||||
|
||||
use cuprate_consensus_rules::blocks::ContextToVerifyBlock;
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use super::{
|
||||
difficulty, hardforks, rx_vms, weight, BlockChainContext, BlockChainContextRequest,
|
||||
BlockChainContextResponse, ContextConfig, RawBlockChainContext, ValidityToken,
|
||||
BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW,
|
||||
};
|
||||
use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError};
|
||||
use crate::{Database, ExtendedConsensusError};
|
||||
|
||||
/// A request from the context service to the context task.
|
||||
pub(super) struct ContextTaskRequest {
|
||||
|
@ -69,19 +70,19 @@ impl ContextTask {
|
|||
|
||||
tracing::debug!("Initialising blockchain context");
|
||||
|
||||
let DatabaseResponse::ChainHeight(chain_height, top_block_hash) = database
|
||||
let BCResponse::ChainHeight(chain_height, top_block_hash) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::ChainHeight)
|
||||
.call(BCReadRequest::ChainHeight)
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
};
|
||||
|
||||
let DatabaseResponse::GeneratedCoins(already_generated_coins) = database
|
||||
let BCResponse::GeneratedCoins(already_generated_coins) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::GeneratedCoins)
|
||||
.call(BCReadRequest::GeneratedCoins)
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
|
|
|
@ -18,8 +18,9 @@ use tracing::instrument;
|
|||
|
||||
use cuprate_consensus_rules::blocks::{penalty_free_zone, PENALTY_FREE_ZONE_5};
|
||||
use cuprate_helper::{asynch::rayon_spawn_async, num::median};
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork};
|
||||
use crate::{Database, ExtendedConsensusError, HardFork};
|
||||
|
||||
/// The short term block weight window.
|
||||
const SHORT_TERM_WINDOW: u64 = 100;
|
||||
|
@ -292,8 +293,8 @@ async fn get_blocks_weight_in_range<D: Database + Clone>(
|
|||
) -> Result<Vec<usize>, ExtendedConsensusError> {
|
||||
tracing::info!("getting block weights.");
|
||||
|
||||
let DatabaseResponse::BlockExtendedHeaderInRange(ext_headers) = database
|
||||
.oneshot(DatabaseRequest::BlockExtendedHeaderInRange(range))
|
||||
let BCResponse::BlockExtendedHeaderInRange(ext_headers) = database
|
||||
.oneshot(BCReadRequest::BlockExtendedHeaderInRange(range))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!")
|
||||
|
@ -313,8 +314,8 @@ async fn get_long_term_weight_in_range<D: Database + Clone>(
|
|||
) -> Result<Vec<usize>, ExtendedConsensusError> {
|
||||
tracing::info!("getting block long term weights.");
|
||||
|
||||
let DatabaseResponse::BlockExtendedHeaderInRange(ext_headers) = database
|
||||
.oneshot(DatabaseRequest::BlockExtendedHeaderInRange(range))
|
||||
let BCResponse::BlockExtendedHeaderInRange(ext_headers) = database
|
||||
.oneshot(BCReadRequest::BlockExtendedHeaderInRange(range))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!")
|
||||
|
|
|
@ -10,12 +10,7 @@
|
|||
//! implement a database you need to have a service which accepts [`DatabaseRequest`] and responds
|
||||
//! with [`DatabaseResponse`].
|
||||
//!
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
future::Future,
|
||||
};
|
||||
|
||||
use cuprate_consensus_rules::{transactions::OutputOnChain, ConsensusError, HardFork};
|
||||
use cuprate_consensus_rules::{ConsensusError, HardFork};
|
||||
|
||||
mod batch_verifier;
|
||||
pub mod block;
|
||||
|
@ -34,6 +29,9 @@ pub use context::{
|
|||
};
|
||||
pub use transactions::{TxVerifierService, VerifyTxRequest, VerifyTxResponse};
|
||||
|
||||
// re-export.
|
||||
pub use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
/// An Error returned from one of the consensus services.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ExtendedConsensusError {
|
||||
|
@ -80,115 +78,36 @@ where
|
|||
Ok((block_svc, tx_svc))
|
||||
}
|
||||
|
||||
/// An internal trait used to represent a database so we don't have to write [`tower::Service`] bounds
|
||||
/// everywhere.
|
||||
pub trait Database:
|
||||
tower::Service<
|
||||
DatabaseRequest,
|
||||
Response = DatabaseResponse,
|
||||
Error = tower::BoxError,
|
||||
Future = Self::Future2,
|
||||
>
|
||||
{
|
||||
type Future2: Future<Output = Result<Self::Response, Self::Error>> + Send + 'static;
|
||||
}
|
||||
use __private::Database;
|
||||
|
||||
impl<T: tower::Service<DatabaseRequest, Response = DatabaseResponse, Error = tower::BoxError>>
|
||||
Database for T
|
||||
where
|
||||
T::Future: Future<Output = Result<Self::Response, Self::Error>> + Send + 'static,
|
||||
{
|
||||
type Future2 = T::Future;
|
||||
}
|
||||
pub mod __private {
|
||||
use std::future::Future;
|
||||
|
||||
/// An extended block header.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ExtendedBlockHeader {
|
||||
/// The blocks major version.
|
||||
pub version: HardFork,
|
||||
/// The blocks vote.
|
||||
pub vote: HardFork,
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
/// The blocks timestamp.
|
||||
pub timestamp: u64,
|
||||
/// The blocks cumulative difficulty.
|
||||
pub cumulative_difficulty: u128,
|
||||
|
||||
/// The blocks weight.
|
||||
pub block_weight: usize,
|
||||
/// The blocks long term weight.
|
||||
pub long_term_weight: usize,
|
||||
}
|
||||
|
||||
/// A database request to the database [`tower::Service`]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DatabaseRequest {
|
||||
/// A block extended header request.
|
||||
/// Must return: [`DatabaseResponse::BlockExtendedHeader`]
|
||||
BlockExtendedHeader(u64),
|
||||
/// A block hash request.
|
||||
/// Must return: [`DatabaseResponse::BlockHash`]
|
||||
BlockHash(u64),
|
||||
|
||||
/// Removes the block hashes that are not in the _main_ chain.
|
||||
/// An internal trait used to represent a database so we don't have to write [`tower::Service`] bounds
|
||||
/// everywhere.
|
||||
///
|
||||
/// This should filter (remove) hashes in alt-blocks as well.
|
||||
FilterUnknownHashes(HashSet<[u8; 32]>),
|
||||
/// Automatically implemented for:
|
||||
/// ```ignore
|
||||
/// tower::Service<BCReadRequest, Response = BCResponse, Error = tower::BoxError>
|
||||
/// ```
|
||||
pub trait Database:
|
||||
tower::Service<
|
||||
BCReadRequest,
|
||||
Response = BCResponse,
|
||||
Error = tower::BoxError,
|
||||
Future = Self::Future2,
|
||||
>
|
||||
{
|
||||
type Future2: Future<Output = Result<Self::Response, Self::Error>> + Send + 'static;
|
||||
}
|
||||
|
||||
/// A request for multiple block extended headers.
|
||||
/// Must return: [`DatabaseResponse::BlockExtendedHeaderInRange`]
|
||||
BlockExtendedHeaderInRange(std::ops::Range<u64>),
|
||||
|
||||
/// A request for the chains height.
|
||||
/// Must return: [`DatabaseResponse::ChainHeight`]
|
||||
ChainHeight,
|
||||
/// A request for the total amount of generated coins.
|
||||
/// Must return: [`DatabaseResponse::GeneratedCoins`]
|
||||
GeneratedCoins,
|
||||
|
||||
/// A request for transaction outputs, this contains a map of amounts to amount indexes.
|
||||
/// Must return: [`DatabaseResponse::Outputs`]
|
||||
Outputs(HashMap<u64, HashSet<u64>>),
|
||||
/// A request for the number of outputs with these amounts.
|
||||
/// Must return: [`DatabaseResponse::NumberOutputsWithAmount`]
|
||||
NumberOutputsWithAmount(Vec<u64>),
|
||||
|
||||
/// A request to check if these key images are in the database.
|
||||
/// Must return: [`DatabaseResponse::KeyImagesSpent`]
|
||||
KeyImagesSpent(HashSet<[u8; 32]>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DatabaseResponse {
|
||||
/// A block extended header response.
|
||||
BlockExtendedHeader(ExtendedBlockHeader),
|
||||
/// A block hash response.
|
||||
BlockHash([u8; 32]),
|
||||
|
||||
FilteredHashes(HashSet<[u8; 32]>),
|
||||
|
||||
/// A batch block extended header response.
|
||||
BlockExtendedHeaderInRange(Vec<ExtendedBlockHeader>),
|
||||
|
||||
/// A chain height response.
|
||||
/// Should contains the chains height and top block hash.
|
||||
ChainHeight(u64, [u8; 32]),
|
||||
/// Generated coins response.
|
||||
/// Should contain the total amount of coins emitted in all block rewards.
|
||||
GeneratedCoins(u64),
|
||||
|
||||
/// Outputs response.
|
||||
/// Should contain a map of (amounts, amount_idx) -> Output.
|
||||
/// If an outputs requested does not exist this should *not* be an error, the output
|
||||
/// should just be omitted from the map.
|
||||
Outputs(HashMap<u64, HashMap<u64, OutputOnChain>>),
|
||||
/// Number of outputs response.
|
||||
/// Should contain a map of amounts -> numb outs.
|
||||
/// If there are no outputs with that amount then the numb outs should be zero, *no* amounts
|
||||
/// requested should be omitted.
|
||||
NumberOutputsWithAmount(HashMap<u64, usize>),
|
||||
|
||||
/// Key images spent response.
|
||||
/// returns true if key images are spent
|
||||
KeyImagesSpent(bool),
|
||||
impl<T: tower::Service<BCReadRequest, Response = BCResponse, Error = tower::BoxError>>
|
||||
crate::Database for T
|
||||
where
|
||||
T::Future: Future<Output = Result<Self::Response, Self::Error>> + Send + 'static,
|
||||
{
|
||||
type Future2 = T::Future;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ use std::{
|
|||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use cuprate_types::{
|
||||
service::{BCReadRequest, BCResponse},
|
||||
ExtendedBlockHeader,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use proptest::{
|
||||
arbitrary::{any, any_with},
|
||||
|
@ -15,7 +19,7 @@ use proptest::{
|
|||
use proptest_derive::Arbitrary;
|
||||
use tower::{BoxError, Service};
|
||||
|
||||
use crate::{DatabaseRequest, DatabaseResponse, ExtendedBlockHeader, HardFork};
|
||||
use crate::HardFork;
|
||||
|
||||
prop_compose! {
|
||||
/// Generates an arbitrary full [`DummyDatabase`], it is not safe to do consensus checks on the returned database
|
||||
|
@ -56,8 +60,8 @@ pub struct DummyBlockExtendedHeader {
|
|||
impl From<DummyBlockExtendedHeader> for ExtendedBlockHeader {
|
||||
fn from(value: DummyBlockExtendedHeader) -> Self {
|
||||
ExtendedBlockHeader {
|
||||
version: value.version.unwrap_or(HardFork::V1),
|
||||
vote: value.vote.unwrap_or(HardFork::V1),
|
||||
version: value.version.unwrap_or(HardFork::V1) as u8,
|
||||
vote: value.vote.unwrap_or(HardFork::V1) as u8,
|
||||
timestamp: value.timestamp.unwrap_or_default(),
|
||||
cumulative_difficulty: value.cumulative_difficulty.unwrap_or_default(),
|
||||
block_weight: value.block_weight.unwrap_or_default(),
|
||||
|
@ -122,8 +126,8 @@ pub struct DummyDatabase {
|
|||
dummy_height: Option<usize>,
|
||||
}
|
||||
|
||||
impl Service<DatabaseRequest> for DummyDatabase {
|
||||
type Response = DatabaseResponse;
|
||||
impl Service<BCReadRequest> for DummyDatabase {
|
||||
type Response = BCResponse;
|
||||
type Error = BoxError;
|
||||
type Future =
|
||||
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
|
||||
|
@ -132,13 +136,13 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: DatabaseRequest) -> Self::Future {
|
||||
fn call(&mut self, req: BCReadRequest) -> Self::Future {
|
||||
let blocks = self.blocks.clone();
|
||||
let dummy_height = self.dummy_height;
|
||||
|
||||
async move {
|
||||
Ok(match req {
|
||||
DatabaseRequest::BlockExtendedHeader(id) => {
|
||||
BCReadRequest::BlockExtendedHeader(id) => {
|
||||
let mut id = usize::try_from(id).unwrap();
|
||||
if let Some(dummy_height) = dummy_height {
|
||||
let block_len = blocks.read().unwrap().len();
|
||||
|
@ -146,7 +150,7 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
id -= dummy_height - block_len;
|
||||
}
|
||||
|
||||
DatabaseResponse::BlockExtendedHeader(
|
||||
BCResponse::BlockExtendedHeader(
|
||||
blocks
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -156,12 +160,12 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
.ok_or("block not in database!")?,
|
||||
)
|
||||
}
|
||||
DatabaseRequest::BlockHash(id) => {
|
||||
BCReadRequest::BlockHash(id) => {
|
||||
let mut hash = [0; 32];
|
||||
hash[0..8].copy_from_slice(&id.to_le_bytes());
|
||||
DatabaseResponse::BlockHash(hash)
|
||||
BCResponse::BlockHash(hash)
|
||||
}
|
||||
DatabaseRequest::BlockExtendedHeaderInRange(range) => {
|
||||
BCReadRequest::BlockExtendedHeaderInRange(range) => {
|
||||
let mut end = usize::try_from(range.end).unwrap();
|
||||
let mut start = usize::try_from(range.start).unwrap();
|
||||
|
||||
|
@ -172,7 +176,7 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
start -= dummy_height - block_len;
|
||||
}
|
||||
|
||||
DatabaseResponse::BlockExtendedHeaderInRange(
|
||||
BCResponse::BlockExtendedHeaderInRange(
|
||||
blocks
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -184,7 +188,7 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
.collect(),
|
||||
)
|
||||
}
|
||||
DatabaseRequest::ChainHeight => {
|
||||
BCReadRequest::ChainHeight => {
|
||||
let height: u64 = dummy_height
|
||||
.unwrap_or(blocks.read().unwrap().len())
|
||||
.try_into()
|
||||
|
@ -193,9 +197,9 @@ impl Service<DatabaseRequest> for DummyDatabase {
|
|||
let mut top_hash = [0; 32];
|
||||
top_hash[0..8].copy_from_slice(&height.to_le_bytes());
|
||||
|
||||
DatabaseResponse::ChainHeight(height, top_hash)
|
||||
BCResponse::ChainHeight(height, top_hash)
|
||||
}
|
||||
DatabaseRequest::GeneratedCoins => DatabaseResponse::GeneratedCoins(0),
|
||||
BCReadRequest::GeneratedCoins => BCResponse::GeneratedCoins(0),
|
||||
_ => unimplemented!("the context svc should not need these requests!"),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -28,11 +28,12 @@ use cuprate_consensus_rules::{
|
|||
ConsensusError, HardFork, TxVersion,
|
||||
};
|
||||
use cuprate_helper::asynch::rayon_spawn_async;
|
||||
use cuprate_types::service::{BCReadRequest, BCResponse};
|
||||
|
||||
use crate::{
|
||||
batch_verifier::MultiThreadedBatchVerifier,
|
||||
transactions::contextual_data::{batch_get_decoy_info, batch_get_ring_member_info},
|
||||
Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError,
|
||||
Database, ExtendedConsensusError,
|
||||
};
|
||||
|
||||
pub mod contextual_data;
|
||||
|
@ -307,10 +308,10 @@ where
|
|||
})
|
||||
})?;
|
||||
|
||||
let DatabaseResponse::KeyImagesSpent(kis_spent) = database
|
||||
let BCResponse::KeyImagesSpent(kis_spent) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::KeyImagesSpent(spent_kis))
|
||||
.call(BCReadRequest::KeyImagesSpent(spent_kis))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!");
|
||||
|
@ -339,12 +340,10 @@ where
|
|||
if !verified_at_block_hashes.is_empty() {
|
||||
tracing::trace!("Filtering block hashes not in the main chain.");
|
||||
|
||||
let DatabaseResponse::FilteredHashes(known_hashes) = database
|
||||
let BCResponse::FilterUnknownHashes(known_hashes) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::FilterUnknownHashes(
|
||||
verified_at_block_hashes,
|
||||
))
|
||||
.call(BCReadRequest::FilterUnknownHashes(verified_at_block_hashes))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database returned wrong response!");
|
||||
|
|
|
@ -15,21 +15,128 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use monero_serai::transaction::Input;
|
||||
use monero_serai::transaction::{Input, Timelock};
|
||||
use tower::ServiceExt;
|
||||
use tracing::instrument;
|
||||
|
||||
use cuprate_consensus_rules::transactions::Rings;
|
||||
use cuprate_consensus_rules::{
|
||||
transactions::{
|
||||
get_ring_members_for_inputs, insert_ring_member_ids, DecoyInfo, TxRingMembersInfo,
|
||||
get_absolute_offsets, insert_ring_member_ids, DecoyInfo, TransactionError,
|
||||
TxRingMembersInfo,
|
||||
},
|
||||
ConsensusError, HardFork,
|
||||
ConsensusError, HardFork, TxVersion,
|
||||
};
|
||||
use cuprate_types::{
|
||||
service::{BCReadRequest, BCResponse},
|
||||
OutputOnChain,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
transactions::TransactionVerificationData, Database, DatabaseRequest, DatabaseResponse,
|
||||
ExtendedConsensusError,
|
||||
};
|
||||
use crate::{transactions::TransactionVerificationData, Database, ExtendedConsensusError};
|
||||
|
||||
/// Get the ring members for the inputs from the outputs on the chain.
|
||||
///
|
||||
/// Will error if `outputs` does not contain the outputs needed.
|
||||
fn get_ring_members_for_inputs(
|
||||
get_outputs: impl Fn(u64, u64) -> Option<OutputOnChain>,
|
||||
inputs: &[Input],
|
||||
) -> Result<Vec<Vec<OutputOnChain>>, TransactionError> {
|
||||
inputs
|
||||
.iter()
|
||||
.map(|inp| match inp {
|
||||
Input::ToKey {
|
||||
amount,
|
||||
key_offsets,
|
||||
..
|
||||
} => {
|
||||
let offsets = get_absolute_offsets(key_offsets)?;
|
||||
Ok(offsets
|
||||
.iter()
|
||||
.map(|offset| {
|
||||
get_outputs(amount.unwrap_or(0), *offset)
|
||||
.ok_or(TransactionError::RingMemberNotFoundOrInvalid)
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()?)
|
||||
}
|
||||
_ => Err(TransactionError::IncorrectInputType),
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()
|
||||
}
|
||||
|
||||
/// Construct a [`TxRingMembersInfo`] struct.
|
||||
///
|
||||
/// The used outs must be all the ring members used in the transactions inputs.
|
||||
pub fn new_ring_member_info(
|
||||
used_outs: Vec<Vec<OutputOnChain>>,
|
||||
decoy_info: Option<DecoyInfo>,
|
||||
tx_version: TxVersion,
|
||||
) -> Result<TxRingMembersInfo, TransactionError> {
|
||||
Ok(TxRingMembersInfo {
|
||||
youngest_used_out_height: used_outs
|
||||
.iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.iter()
|
||||
// the output with the highest height is the youngest
|
||||
.map(|out| out.height)
|
||||
.max()
|
||||
.expect("Input must have ring members")
|
||||
})
|
||||
.max()
|
||||
.expect("Tx must have inputs"),
|
||||
time_locked_outs: used_outs
|
||||
.iter()
|
||||
.flat_map(|inp_outs| {
|
||||
inp_outs
|
||||
.iter()
|
||||
.filter_map(|out| match out.time_lock {
|
||||
Timelock::None => None,
|
||||
lock => Some(lock),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect(),
|
||||
rings: new_rings(used_outs, tx_version)?,
|
||||
decoy_info,
|
||||
})
|
||||
}
|
||||
|
||||
/// Builds the [`Rings`] for the transaction inputs, from the given outputs.
|
||||
fn new_rings(
|
||||
outputs: Vec<Vec<OutputOnChain>>,
|
||||
tx_version: TxVersion,
|
||||
) -> Result<Rings, TransactionError> {
|
||||
Ok(match tx_version {
|
||||
TxVersion::RingSignatures => Rings::Legacy(
|
||||
outputs
|
||||
.into_iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.into_iter()
|
||||
.map(|out| out.key.ok_or(TransactionError::RingMemberNotFoundOrInvalid))
|
||||
.collect::<Result<Vec<_>, TransactionError>>()
|
||||
})
|
||||
.collect::<Result<Vec<_>, TransactionError>>()?,
|
||||
),
|
||||
TxVersion::RingCT => Rings::RingCT(
|
||||
outputs
|
||||
.into_iter()
|
||||
.map(|inp_outs| {
|
||||
inp_outs
|
||||
.into_iter()
|
||||
.map(|out| {
|
||||
Ok([
|
||||
out.key
|
||||
.ok_or(TransactionError::RingMemberNotFoundOrInvalid)?,
|
||||
out.commitment,
|
||||
])
|
||||
})
|
||||
.collect::<Result<_, TransactionError>>()
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
/// Retrieves the [`TxRingMembersInfo`] for the inputted [`TransactionVerificationData`].
|
||||
///
|
||||
|
@ -47,19 +154,19 @@ pub async fn batch_get_ring_member_info<D: Database>(
|
|||
.map_err(ConsensusError::Transaction)?;
|
||||
}
|
||||
|
||||
let DatabaseResponse::Outputs(outputs) = database
|
||||
let BCResponse::Outputs(outputs) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::Outputs(output_ids))
|
||||
.call(BCReadRequest::Outputs(output_ids))
|
||||
.await?
|
||||
else {
|
||||
panic!("Database sent incorrect response!")
|
||||
};
|
||||
|
||||
let DatabaseResponse::NumberOutputsWithAmount(outputs_with_amount) = database
|
||||
let BCResponse::NumberOutputsWithAmount(outputs_with_amount) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::NumberOutputsWithAmount(
|
||||
.call(BCReadRequest::NumberOutputsWithAmount(
|
||||
outputs.keys().copied().collect(),
|
||||
))
|
||||
.await?
|
||||
|
@ -87,7 +194,7 @@ pub async fn batch_get_ring_member_info<D: Database>(
|
|||
None
|
||||
};
|
||||
|
||||
TxRingMembersInfo::new(ring_members_for_tx, decoy_info, tx_v_data.version)
|
||||
new_ring_member_info(ring_members_for_tx, decoy_info, tx_v_data.version)
|
||||
.map_err(ConsensusError::Transaction)
|
||||
})
|
||||
.collect::<Result<_, _>>()?)
|
||||
|
@ -128,10 +235,10 @@ pub async fn batch_get_decoy_info<'a, D: Database + Clone + Send + 'static>(
|
|||
unique_input_amounts.len()
|
||||
);
|
||||
|
||||
let DatabaseResponse::NumberOutputsWithAmount(outputs_with_amount) = database
|
||||
let BCResponse::NumberOutputsWithAmount(outputs_with_amount) = database
|
||||
.ready()
|
||||
.await?
|
||||
.call(DatabaseRequest::NumberOutputsWithAmount(
|
||||
.call(BCReadRequest::NumberOutputsWithAmount(
|
||||
unique_input_amounts.into_iter().collect(),
|
||||
))
|
||||
.await?
|
||||
|
|
|
@ -4,28 +4,31 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use cuprate_types::{
|
||||
service::{BCReadRequest, BCResponse},
|
||||
OutputOnChain,
|
||||
};
|
||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, edwards::CompressedEdwardsY};
|
||||
use monero_serai::transaction::{Timelock, Transaction};
|
||||
use tower::{service_fn, Service, ServiceExt};
|
||||
|
||||
use cuprate_consensus::{
|
||||
Database, DatabaseRequest, DatabaseResponse, TxVerifierService, VerifyTxRequest,
|
||||
VerifyTxResponse,
|
||||
TxVerifierService, VerifyTxRequest, VerifyTxResponse, __private::Database,
|
||||
};
|
||||
|
||||
use cuprate_consensus_rules::{transactions::OutputOnChain, HardFork};
|
||||
use cuprate_consensus_rules::HardFork;
|
||||
|
||||
use cuprate_test_utils::data::TX_E2D393;
|
||||
|
||||
fn dummy_database(outputs: BTreeMap<u64, OutputOnChain>) -> impl Database + Clone {
|
||||
let outputs = Arc::new(outputs);
|
||||
|
||||
service_fn(move |req: DatabaseRequest| {
|
||||
service_fn(move |req: BCReadRequest| {
|
||||
ready(Ok(match req {
|
||||
DatabaseRequest::NumberOutputsWithAmount(_) => {
|
||||
DatabaseResponse::NumberOutputsWithAmount(HashMap::new())
|
||||
BCReadRequest::NumberOutputsWithAmount(_) => {
|
||||
BCResponse::NumberOutputsWithAmount(HashMap::new())
|
||||
}
|
||||
DatabaseRequest::Outputs(outs) => {
|
||||
BCReadRequest::Outputs(outs) => {
|
||||
let idxs = outs.get(&0).unwrap();
|
||||
|
||||
let mut ret = HashMap::new();
|
||||
|
@ -37,9 +40,9 @@ fn dummy_database(outputs: BTreeMap<u64, OutputOnChain>) -> impl Database + Clon
|
|||
.collect::<HashMap<_, _>>(),
|
||||
);
|
||||
|
||||
DatabaseResponse::Outputs(ret)
|
||||
BCResponse::Outputs(ret)
|
||||
}
|
||||
DatabaseRequest::KeyImagesSpent(_) => DatabaseResponse::KeyImagesSpent(false),
|
||||
BCReadRequest::KeyImagesSpent(_) => BCResponse::KeyImagesSpent(false),
|
||||
_ => panic!("Database request not needed for this test"),
|
||||
}))
|
||||
})
|
||||
|
|
|
@ -50,11 +50,11 @@
|
|||
//! This channel can be `.await`ed upon to (eventually) receive
|
||||
//! the corresponding `Response` to your `Request`.
|
||||
//!
|
||||
//! [req_r]: cuprate_types::service::ReadRequest
|
||||
//! [req_r]: cuprate_types::service::BCReadRequest
|
||||
//!
|
||||
//! [req_w]: cuprate_types::service::WriteRequest
|
||||
//! [req_w]: cuprate_types::service::BCWriteRequest
|
||||
//!
|
||||
//! [resp]: cuprate_types::service::Response
|
||||
//! [resp]: cuprate_types::service::BCResponse
|
||||
//!
|
||||
//! # Example
|
||||
//! Simple usage of `service`.
|
||||
|
@ -63,7 +63,7 @@
|
|||
//! use hex_literal::hex;
|
||||
//! use tower::{Service, ServiceExt};
|
||||
//!
|
||||
//! use cuprate_types::service::{ReadRequest, WriteRequest, Response};
|
||||
//! use cuprate_types::service::{BCReadRequest, BCWriteRequest, BCResponse};
|
||||
//! use cuprate_test_utils::data::block_v16_tx0;
|
||||
//!
|
||||
//! use cuprate_blockchain::{ConcreteEnv, config::ConfigBuilder, Env};
|
||||
|
@ -82,7 +82,7 @@
|
|||
//! // Prepare a request to write block.
|
||||
//! let mut block = block_v16_tx0().clone();
|
||||
//! # block.height = 0 as u64; // must be 0th height or panic in `add_block()`
|
||||
//! let request = WriteRequest::WriteBlock(block);
|
||||
//! let request = BCWriteRequest::WriteBlock(block);
|
||||
//!
|
||||
//! // Send the request.
|
||||
//! // We receive back an `async` channel that will
|
||||
|
@ -92,16 +92,16 @@
|
|||
//!
|
||||
//! // Block write was OK.
|
||||
//! let response = response_channel.await?;
|
||||
//! assert_eq!(response, Response::WriteBlockOk);
|
||||
//! assert_eq!(response, BCResponse::WriteBlockOk);
|
||||
//!
|
||||
//! // Now, let's try getting the block hash
|
||||
//! // of the block we just wrote.
|
||||
//! let request = ReadRequest::BlockHash(0);
|
||||
//! let request = BCReadRequest::BlockHash(0);
|
||||
//! let response_channel = read_handle.ready().await?.call(request);
|
||||
//! let response = response_channel.await?;
|
||||
//! assert_eq!(
|
||||
//! response,
|
||||
//! Response::BlockHash(
|
||||
//! BCResponse::BlockHash(
|
||||
//! hex!("43bd1f2b6556dcafa413d8372974af59e4e8f37dbf74dc6b2a9b7212d0577428")
|
||||
//! )
|
||||
//! );
|
||||
|
|
|
@ -15,7 +15,7 @@ use tokio_util::sync::PollSemaphore;
|
|||
|
||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||
use cuprate_types::{
|
||||
service::{ReadRequest, Response},
|
||||
service::{BCReadRequest, BCResponse},
|
||||
ExtendedBlockHeader, OutputOnChain,
|
||||
};
|
||||
|
||||
|
@ -40,9 +40,9 @@ use crate::{
|
|||
/// This is cheaply [`Clone`]able handle that
|
||||
/// allows `async`hronously reading from the database.
|
||||
///
|
||||
/// Calling [`tower::Service::call`] with a [`DatabaseReadHandle`] & [`ReadRequest`]
|
||||
/// Calling [`tower::Service::call`] with a [`DatabaseReadHandle`] & [`BCReadRequest`]
|
||||
/// will return an `async`hronous channel that can be `.await`ed upon
|
||||
/// to receive the corresponding [`Response`].
|
||||
/// to receive the corresponding [`BCResponse`].
|
||||
pub struct DatabaseReadHandle {
|
||||
/// Handle to the custom `rayon` DB reader thread-pool.
|
||||
///
|
||||
|
@ -131,8 +131,8 @@ impl DatabaseReadHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl tower::Service<ReadRequest> for DatabaseReadHandle {
|
||||
type Response = Response;
|
||||
impl tower::Service<BCReadRequest> for DatabaseReadHandle {
|
||||
type Response = BCResponse;
|
||||
type Error = RuntimeError;
|
||||
type Future = ResponseReceiver;
|
||||
|
||||
|
@ -152,7 +152,7 @@ impl tower::Service<ReadRequest> for DatabaseReadHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn call(&mut self, request: ReadRequest) -> Self::Future {
|
||||
fn call(&mut self, request: BCReadRequest) -> Self::Future {
|
||||
let permit = self
|
||||
.permit
|
||||
.take()
|
||||
|
@ -189,13 +189,13 @@ impl tower::Service<ReadRequest> for DatabaseReadHandle {
|
|||
/// The basic structure is:
|
||||
/// 1. `Request` is mapped to a handler function
|
||||
/// 2. Handler function is called
|
||||
/// 3. [`Response`] is sent
|
||||
/// 3. [`BCResponse`] is sent
|
||||
fn map_request(
|
||||
env: &ConcreteEnv, // Access to the database
|
||||
request: ReadRequest, // The request we must fulfill
|
||||
request: BCReadRequest, // The request we must fulfill
|
||||
response_sender: ResponseSender, // The channel we must send the response back to
|
||||
) {
|
||||
use ReadRequest as R;
|
||||
use BCReadRequest as R;
|
||||
|
||||
/* SOMEDAY: pre-request handling, run some code for each request? */
|
||||
|
||||
|
@ -286,7 +286,7 @@ macro_rules! get_tables {
|
|||
// FIXME: implement multi-transaction read atomicity.
|
||||
// <https://github.com/Cuprate/cuprate/pull/113#discussion_r1576874589>.
|
||||
|
||||
/// [`ReadRequest::BlockExtendedHeader`].
|
||||
/// [`BCReadRequest::BlockExtendedHeader`].
|
||||
#[inline]
|
||||
fn block_extended_header(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult {
|
||||
// Single-threaded, no `ThreadLocal` required.
|
||||
|
@ -294,12 +294,12 @@ fn block_extended_header(env: &ConcreteEnv, block_height: BlockHeight) -> Respon
|
|||
let tx_ro = env_inner.tx_ro()?;
|
||||
let tables = env_inner.open_tables(&tx_ro)?;
|
||||
|
||||
Ok(Response::BlockExtendedHeader(
|
||||
Ok(BCResponse::BlockExtendedHeader(
|
||||
get_block_extended_header_from_height(&block_height, &tables)?,
|
||||
))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::BlockHash`].
|
||||
/// [`BCReadRequest::BlockHash`].
|
||||
#[inline]
|
||||
fn block_hash(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult {
|
||||
// Single-threaded, no `ThreadLocal` required.
|
||||
|
@ -307,12 +307,12 @@ fn block_hash(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult {
|
|||
let tx_ro = env_inner.tx_ro()?;
|
||||
let table_block_infos = env_inner.open_db_ro::<BlockInfos>(&tx_ro)?;
|
||||
|
||||
Ok(Response::BlockHash(
|
||||
Ok(BCResponse::BlockHash(
|
||||
get_block_info(&block_height, &table_block_infos)?.block_hash,
|
||||
))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::BlockExtendedHeaderInRange`].
|
||||
/// [`BCReadRequest::BlockExtendedHeaderInRange`].
|
||||
#[inline]
|
||||
fn block_extended_header_in_range(
|
||||
env: &ConcreteEnv,
|
||||
|
@ -333,10 +333,10 @@ fn block_extended_header_in_range(
|
|||
})
|
||||
.collect::<Result<Vec<ExtendedBlockHeader>, RuntimeError>>()?;
|
||||
|
||||
Ok(Response::BlockExtendedHeaderInRange(vec))
|
||||
Ok(BCResponse::BlockExtendedHeaderInRange(vec))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::ChainHeight`].
|
||||
/// [`BCReadRequest::ChainHeight`].
|
||||
#[inline]
|
||||
fn chain_height(env: &ConcreteEnv) -> ResponseResult {
|
||||
// Single-threaded, no `ThreadLocal` required.
|
||||
|
@ -349,10 +349,10 @@ fn chain_height(env: &ConcreteEnv) -> ResponseResult {
|
|||
let block_hash =
|
||||
get_block_info(&chain_height.saturating_sub(1), &table_block_infos)?.block_hash;
|
||||
|
||||
Ok(Response::ChainHeight(chain_height, block_hash))
|
||||
Ok(BCResponse::ChainHeight(chain_height, block_hash))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::GeneratedCoins`].
|
||||
/// [`BCReadRequest::GeneratedCoins`].
|
||||
#[inline]
|
||||
fn generated_coins(env: &ConcreteEnv) -> ResponseResult {
|
||||
// Single-threaded, no `ThreadLocal` required.
|
||||
|
@ -363,13 +363,13 @@ fn generated_coins(env: &ConcreteEnv) -> ResponseResult {
|
|||
|
||||
let top_height = top_block_height(&table_block_heights)?;
|
||||
|
||||
Ok(Response::GeneratedCoins(cumulative_generated_coins(
|
||||
Ok(BCResponse::GeneratedCoins(cumulative_generated_coins(
|
||||
&top_height,
|
||||
&table_block_infos,
|
||||
)?))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::Outputs`].
|
||||
/// [`BCReadRequest::Outputs`].
|
||||
#[inline]
|
||||
fn outputs(env: &ConcreteEnv, outputs: HashMap<Amount, HashSet<AmountIndex>>) -> ResponseResult {
|
||||
// Prepare tx/tables in `ThreadLocal`.
|
||||
|
@ -407,10 +407,10 @@ fn outputs(env: &ConcreteEnv, outputs: HashMap<Amount, HashSet<AmountIndex>>) ->
|
|||
})
|
||||
.collect::<Result<HashMap<Amount, HashMap<AmountIndex, OutputOnChain>>, RuntimeError>>()?;
|
||||
|
||||
Ok(Response::Outputs(map))
|
||||
Ok(BCResponse::Outputs(map))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::NumberOutputsWithAmount`].
|
||||
/// [`BCReadRequest::NumberOutputsWithAmount`].
|
||||
#[inline]
|
||||
fn number_outputs_with_amount(env: &ConcreteEnv, amounts: Vec<Amount>) -> ResponseResult {
|
||||
// Prepare tx/tables in `ThreadLocal`.
|
||||
|
@ -452,10 +452,10 @@ fn number_outputs_with_amount(env: &ConcreteEnv, amounts: Vec<Amount>) -> Respon
|
|||
})
|
||||
.collect::<Result<HashMap<Amount, usize>, RuntimeError>>()?;
|
||||
|
||||
Ok(Response::NumberOutputsWithAmount(map))
|
||||
Ok(BCResponse::NumberOutputsWithAmount(map))
|
||||
}
|
||||
|
||||
/// [`ReadRequest::CheckKIsNotSpent`].
|
||||
/// [`BCReadRequest::CheckKIsNotSpent`].
|
||||
#[inline]
|
||||
fn check_k_is_not_spent(env: &ConcreteEnv, key_images: HashSet<KeyImage>) -> ResponseResult {
|
||||
// Prepare tx/tables in `ThreadLocal`.
|
||||
|
@ -486,8 +486,8 @@ fn check_k_is_not_spent(env: &ConcreteEnv, key_images: HashSet<KeyImage>) -> Res
|
|||
// Else, `Ok(false)` will continue the iterator.
|
||||
.find_any(|result| !matches!(result, Ok(false)))
|
||||
{
|
||||
None | Some(Ok(false)) => Ok(Response::CheckKIsNotSpent(true)), // Key image was NOT found.
|
||||
Some(Ok(true)) => Ok(Response::CheckKIsNotSpent(false)), // Key image was found.
|
||||
None | Some(Ok(false)) => Ok(BCResponse::CheckKIsNotSpent(true)), // Key image was NOT found.
|
||||
Some(Ok(true)) => Ok(BCResponse::CheckKIsNotSpent(false)), // Key image was found.
|
||||
Some(Err(e)) => Err(e), // A database error occurred.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use tower::{Service, ServiceExt};
|
|||
|
||||
use cuprate_test_utils::data::{block_v16_tx0, block_v1_tx2, block_v9_tx3};
|
||||
use cuprate_types::{
|
||||
service::{ReadRequest, Response, WriteRequest},
|
||||
service::{BCReadRequest, BCResponse, BCWriteRequest},
|
||||
OutputOnChain, VerifiedBlockInformation,
|
||||
};
|
||||
|
||||
|
@ -81,10 +81,10 @@ async fn test_template(
|
|||
block.height = i as u64;
|
||||
|
||||
// Request a block to be written, assert it was written.
|
||||
let request = WriteRequest::WriteBlock(block);
|
||||
let request = BCWriteRequest::WriteBlock(block);
|
||||
let response_channel = writer.call(request);
|
||||
let response = response_channel.await.unwrap();
|
||||
assert_eq!(response, Response::WriteBlockOk);
|
||||
assert_eq!(response, BCResponse::WriteBlockOk);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------- Reset the transaction
|
||||
|
@ -100,36 +100,36 @@ async fn test_template(
|
|||
// Next few lines are just for preparing the expected responses,
|
||||
// see further below for usage.
|
||||
|
||||
let extended_block_header_0 = Ok(Response::BlockExtendedHeader(
|
||||
let extended_block_header_0 = Ok(BCResponse::BlockExtendedHeader(
|
||||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
));
|
||||
|
||||
let extended_block_header_1 = if block_fns.len() > 1 {
|
||||
Ok(Response::BlockExtendedHeader(
|
||||
Ok(BCResponse::BlockExtendedHeader(
|
||||
get_block_extended_header_from_height(&1, &tables).unwrap(),
|
||||
))
|
||||
} else {
|
||||
Err(RuntimeError::KeyNotFound)
|
||||
};
|
||||
|
||||
let block_hash_0 = Ok(Response::BlockHash(
|
||||
let block_hash_0 = Ok(BCResponse::BlockHash(
|
||||
get_block_info(&0, tables.block_infos()).unwrap().block_hash,
|
||||
));
|
||||
|
||||
let block_hash_1 = if block_fns.len() > 1 {
|
||||
Ok(Response::BlockHash(
|
||||
Ok(BCResponse::BlockHash(
|
||||
get_block_info(&1, tables.block_infos()).unwrap().block_hash,
|
||||
))
|
||||
} else {
|
||||
Err(RuntimeError::KeyNotFound)
|
||||
};
|
||||
|
||||
let range_0_1 = Ok(Response::BlockExtendedHeaderInRange(vec![
|
||||
let range_0_1 = Ok(BCResponse::BlockExtendedHeaderInRange(vec![
|
||||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
]));
|
||||
|
||||
let range_0_2 = if block_fns.len() >= 2 {
|
||||
Ok(Response::BlockExtendedHeaderInRange(vec![
|
||||
Ok(BCResponse::BlockExtendedHeaderInRange(vec![
|
||||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
get_block_extended_header_from_height(&1, &tables).unwrap(),
|
||||
]))
|
||||
|
@ -140,10 +140,10 @@ async fn test_template(
|
|||
let chain_height = {
|
||||
let height = chain_height(tables.block_heights()).unwrap();
|
||||
let block_info = get_block_info(&height.saturating_sub(1), tables.block_infos()).unwrap();
|
||||
Ok(Response::ChainHeight(height, block_info.block_hash))
|
||||
Ok(BCResponse::ChainHeight(height, block_info.block_hash))
|
||||
};
|
||||
|
||||
let cumulative_generated_coins = Ok(Response::GeneratedCoins(cumulative_generated_coins));
|
||||
let cumulative_generated_coins = Ok(BCResponse::GeneratedCoins(cumulative_generated_coins));
|
||||
|
||||
let num_req = tables
|
||||
.outputs_iter()
|
||||
|
@ -153,7 +153,7 @@ async fn test_template(
|
|||
.map(|key| key.amount)
|
||||
.collect::<Vec<Amount>>();
|
||||
|
||||
let num_resp = Ok(Response::NumberOutputsWithAmount(
|
||||
let num_resp = Ok(BCResponse::NumberOutputsWithAmount(
|
||||
num_req
|
||||
.iter()
|
||||
.map(|amount| match tables.num_outputs().get(amount) {
|
||||
|
@ -168,21 +168,27 @@ async fn test_template(
|
|||
|
||||
// Contains a fake non-spent key-image.
|
||||
let ki_req = HashSet::from([[0; 32]]);
|
||||
let ki_resp = Ok(Response::CheckKIsNotSpent(true));
|
||||
let ki_resp = Ok(BCResponse::CheckKIsNotSpent(true));
|
||||
|
||||
//----------------------------------------------------------------------- Assert expected response
|
||||
// Assert read requests lead to the expected responses.
|
||||
for (request, expected_response) in [
|
||||
(ReadRequest::BlockExtendedHeader(0), extended_block_header_0),
|
||||
(ReadRequest::BlockExtendedHeader(1), extended_block_header_1),
|
||||
(ReadRequest::BlockHash(0), block_hash_0),
|
||||
(ReadRequest::BlockHash(1), block_hash_1),
|
||||
(ReadRequest::BlockExtendedHeaderInRange(0..1), range_0_1),
|
||||
(ReadRequest::BlockExtendedHeaderInRange(0..2), range_0_2),
|
||||
(ReadRequest::ChainHeight, chain_height),
|
||||
(ReadRequest::GeneratedCoins, cumulative_generated_coins),
|
||||
(ReadRequest::NumberOutputsWithAmount(num_req), num_resp),
|
||||
(ReadRequest::CheckKIsNotSpent(ki_req), ki_resp),
|
||||
(
|
||||
BCReadRequest::BlockExtendedHeader(0),
|
||||
extended_block_header_0,
|
||||
),
|
||||
(
|
||||
BCReadRequest::BlockExtendedHeader(1),
|
||||
extended_block_header_1,
|
||||
),
|
||||
(BCReadRequest::BlockHash(0), block_hash_0),
|
||||
(BCReadRequest::BlockHash(1), block_hash_1),
|
||||
(BCReadRequest::BlockExtendedHeaderInRange(0..1), range_0_1),
|
||||
(BCReadRequest::BlockExtendedHeaderInRange(0..2), range_0_2),
|
||||
(BCReadRequest::ChainHeight, chain_height),
|
||||
(BCReadRequest::GeneratedCoins, cumulative_generated_coins),
|
||||
(BCReadRequest::NumberOutputsWithAmount(num_req), num_resp),
|
||||
(BCReadRequest::CheckKIsNotSpent(ki_req), ki_resp),
|
||||
] {
|
||||
let response = reader.clone().oneshot(request).await;
|
||||
println!("response: {response:#?}, expected_response: {expected_response:#?}");
|
||||
|
@ -196,10 +202,10 @@ async fn test_template(
|
|||
// Assert each key image we inserted comes back as "spent".
|
||||
for key_image in tables.key_images_iter().keys().unwrap() {
|
||||
let key_image = key_image.unwrap();
|
||||
let request = ReadRequest::CheckKIsNotSpent(HashSet::from([key_image]));
|
||||
let request = BCReadRequest::CheckKIsNotSpent(HashSet::from([key_image]));
|
||||
let response = reader.clone().oneshot(request).await;
|
||||
println!("response: {response:#?}, key_image: {key_image:#?}");
|
||||
assert_eq!(response.unwrap(), Response::CheckKIsNotSpent(false));
|
||||
assert_eq!(response.unwrap(), BCResponse::CheckKIsNotSpent(false));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------- Output checks
|
||||
|
@ -260,10 +266,10 @@ async fn test_template(
|
|||
.collect::<Vec<OutputOnChain>>();
|
||||
|
||||
// Send a request for every output we inserted before.
|
||||
let request = ReadRequest::Outputs(map.clone());
|
||||
let request = BCReadRequest::Outputs(map.clone());
|
||||
let response = reader.clone().oneshot(request).await;
|
||||
println!("Response::Outputs response: {response:#?}");
|
||||
let Ok(Response::Outputs(response)) = response else {
|
||||
let Ok(BCResponse::Outputs(response)) = response else {
|
||||
panic!("{response:#?}")
|
||||
};
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
use futures::channel::oneshot::Sender;
|
||||
|
||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||
use cuprate_types::service::Response;
|
||||
use cuprate_types::service::BCResponse;
|
||||
|
||||
use crate::error::RuntimeError;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Types
|
||||
/// The actual type of the response.
|
||||
///
|
||||
/// Either our [`Response`], or a database error occurred.
|
||||
pub(super) type ResponseResult = Result<Response, RuntimeError>;
|
||||
/// Either our [`BCResponse`], or a database error occurred.
|
||||
pub(super) type ResponseResult = Result<BCResponse, RuntimeError>;
|
||||
|
||||
/// The `Receiver` channel that receives the read response.
|
||||
///
|
||||
|
|
|
@ -10,7 +10,7 @@ use futures::channel::oneshot;
|
|||
|
||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||
use cuprate_types::{
|
||||
service::{Response, WriteRequest},
|
||||
service::{BCResponse, BCWriteRequest},
|
||||
VerifiedBlockInformation,
|
||||
};
|
||||
|
||||
|
@ -33,15 +33,15 @@ const WRITER_THREAD_NAME: &str = concat!(module_path!(), "::DatabaseWriter");
|
|||
/// it is not [`Clone`]able as there is only ever 1 place within Cuprate
|
||||
/// that writes.
|
||||
///
|
||||
/// Calling [`tower::Service::call`] with a [`DatabaseWriteHandle`] & [`WriteRequest`]
|
||||
/// Calling [`tower::Service::call`] with a [`DatabaseWriteHandle`] & [`BCWriteRequest`]
|
||||
/// will return an `async`hronous channel that can be `.await`ed upon
|
||||
/// to receive the corresponding [`Response`].
|
||||
/// to receive the corresponding [`BCResponse`].
|
||||
#[derive(Debug)]
|
||||
pub struct DatabaseWriteHandle {
|
||||
/// Sender channel to the database write thread-pool.
|
||||
///
|
||||
/// We provide the response channel for the thread-pool.
|
||||
pub(super) sender: crossbeam::channel::Sender<(WriteRequest, ResponseSender)>,
|
||||
pub(super) sender: crossbeam::channel::Sender<(BCWriteRequest, ResponseSender)>,
|
||||
}
|
||||
|
||||
impl DatabaseWriteHandle {
|
||||
|
@ -65,8 +65,8 @@ impl DatabaseWriteHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl tower::Service<WriteRequest> for DatabaseWriteHandle {
|
||||
type Response = Response;
|
||||
impl tower::Service<BCWriteRequest> for DatabaseWriteHandle {
|
||||
type Response = BCResponse;
|
||||
type Error = RuntimeError;
|
||||
type Future = ResponseReceiver;
|
||||
|
||||
|
@ -76,7 +76,7 @@ impl tower::Service<WriteRequest> for DatabaseWriteHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn call(&mut self, request: WriteRequest) -> Self::Future {
|
||||
fn call(&mut self, request: BCWriteRequest) -> Self::Future {
|
||||
// Response channel we `.await` on.
|
||||
let (response_sender, receiver) = oneshot::channel();
|
||||
|
||||
|
@ -95,7 +95,7 @@ pub(super) struct DatabaseWriter {
|
|||
/// Any caller can send some requests to this channel.
|
||||
/// They send them alongside another `Response` channel,
|
||||
/// which we will eventually send to.
|
||||
receiver: crossbeam::channel::Receiver<(WriteRequest, ResponseSender)>,
|
||||
receiver: crossbeam::channel::Receiver<(BCWriteRequest, ResponseSender)>,
|
||||
|
||||
/// Access to the database.
|
||||
env: Arc<ConcreteEnv>,
|
||||
|
@ -153,7 +153,7 @@ impl DatabaseWriter {
|
|||
// FIXME: will there be more than 1 write request?
|
||||
// this won't have to be an enum.
|
||||
let response = match &request {
|
||||
WriteRequest::WriteBlock(block) => write_block(&self.env, block),
|
||||
BCWriteRequest::WriteBlock(block) => write_block(&self.env, block),
|
||||
};
|
||||
|
||||
// If the database needs to resize, do so.
|
||||
|
@ -218,7 +218,7 @@ impl DatabaseWriter {
|
|||
// Each function will return the [`Response`] that we
|
||||
// should send back to the caller in [`map_request()`].
|
||||
|
||||
/// [`WriteRequest::WriteBlock`].
|
||||
/// [`BCWriteRequest::WriteBlock`].
|
||||
#[inline]
|
||||
fn write_block(env: &ConcreteEnv, block: &VerifiedBlockInformation) -> ResponseResult {
|
||||
let env_inner = env.env_inner();
|
||||
|
@ -232,7 +232,7 @@ fn write_block(env: &ConcreteEnv, block: &VerifiedBlockInformation) -> ResponseR
|
|||
match result {
|
||||
Ok(()) => {
|
||||
TxRw::commit(tx_rw)?;
|
||||
Ok(Response::WriteBlockOk)
|
||||
Ok(BCResponse::WriteBlockOk)
|
||||
}
|
||||
Err(e) => {
|
||||
// INVARIANT: ensure database atomicity by aborting
|
||||
|
|
|
@ -13,10 +13,7 @@ default = ["service"]
|
|||
service = []
|
||||
|
||||
[dependencies]
|
||||
borsh = { workspace = true, optional = true }
|
||||
cfg-if = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
|
@ -92,10 +92,7 @@ pub use types::{
|
|||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "service")] {
|
||||
pub mod service;
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "service")]
|
||||
pub mod service;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Private
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
//! Database [`ReadRequest`]s, [`WriteRequest`]s, and [`Response`]s.
|
||||
//!
|
||||
//! See [`cuprate_database`](https://github.com/Cuprate/cuprate/blob/00c3692eac6b2669e74cfd8c9b41c7e704c779ad/database/src/service/mod.rs#L1-L59)'s
|
||||
//! `service` module for more usage/documentation.
|
||||
//! Database [`BCReadRequest`]s, [`BCWriteRequest`]s, and [`BCResponse`]s.
|
||||
//!
|
||||
//! Tests that assert particular requests lead to particular
|
||||
//! responses are also tested in `cuprate_database`.
|
||||
//! responses are also tested in Cuprate's blockchain database crate.
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{
|
||||
|
@ -20,18 +17,16 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::types::{ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- ReadRequest
|
||||
/// A read request to the database.
|
||||
/// A read request to the blockchain database.
|
||||
///
|
||||
/// This pairs with [`Response`], where each variant here
|
||||
/// matches in name with a `Response` variant. For example,
|
||||
/// the proper response for a [`ReadRequest::BlockHash`]
|
||||
/// would be a [`Response::BlockHash`].
|
||||
/// This pairs with [`BCResponse`], where each variant here
|
||||
/// matches in name with a [`BCResponse`] variant. For example,
|
||||
/// the proper response for a [`BCReadRequest::BlockHash`]
|
||||
/// would be a [`BCResponse::BlockHash`].
|
||||
///
|
||||
/// See `Response` for the expected responses per `Request`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
pub enum ReadRequest {
|
||||
pub enum BCReadRequest {
|
||||
/// Request a block's extended header.
|
||||
///
|
||||
/// The input is the block's height.
|
||||
|
@ -42,6 +37,11 @@ pub enum ReadRequest {
|
|||
/// The input is the block's height.
|
||||
BlockHash(u64),
|
||||
|
||||
/// Removes the block hashes that are not in the _main_ chain.
|
||||
///
|
||||
/// This should filter (remove) hashes in alt-blocks as well.
|
||||
FilterUnknownHashes(HashSet<[u8; 32]>),
|
||||
|
||||
/// Request a range of block extended headers.
|
||||
///
|
||||
/// The input is a range of block heights.
|
||||
|
@ -86,18 +86,17 @@ pub enum ReadRequest {
|
|||
/// Check that all key images within a set arer not spent.
|
||||
///
|
||||
/// Input is a set of key images.
|
||||
CheckKIsNotSpent(HashSet<[u8; 32]>),
|
||||
KeyImagesSpent(HashSet<[u8; 32]>),
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- WriteRequest
|
||||
/// A write request to the database.
|
||||
/// A write request to the blockchain database.
|
||||
///
|
||||
/// There is currently only 1 write request to the database,
|
||||
/// as such, the only valid [`Response`] to this request is
|
||||
/// the proper response for a [`Response::WriteBlockOk`].
|
||||
/// as such, the only valid [`BCResponse`] to this request is
|
||||
/// the proper response for a [`BCResponse::WriteBlockOk`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
pub enum WriteRequest {
|
||||
pub enum BCWriteRequest {
|
||||
/// Request that a block be written to the database.
|
||||
///
|
||||
/// Input is an already verified block.
|
||||
|
@ -109,60 +108,64 @@ pub enum WriteRequest {
|
|||
///
|
||||
/// These are the data types returned when using sending a `Request`.
|
||||
///
|
||||
/// This pairs with [`ReadRequest`] and [`WriteRequest`],
|
||||
/// This pairs with [`BCReadRequest`] and [`BCWriteRequest`],
|
||||
/// see those two for more info.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
pub enum Response {
|
||||
pub enum BCResponse {
|
||||
//------------------------------------------------------ Reads
|
||||
/// Response to [`ReadRequest::BlockExtendedHeader`].
|
||||
/// Response to [`BCReadRequest::BlockExtendedHeader`].
|
||||
///
|
||||
/// Inner value is the extended headed of the requested block.
|
||||
BlockExtendedHeader(ExtendedBlockHeader),
|
||||
|
||||
/// Response to [`ReadRequest::BlockHash`].
|
||||
/// Response to [`BCReadRequest::BlockHash`].
|
||||
///
|
||||
/// Inner value is the hash of the requested block.
|
||||
BlockHash([u8; 32]),
|
||||
|
||||
/// Response to [`ReadRequest::BlockExtendedHeaderInRange`].
|
||||
/// Response tp [`BCReadRequest::FilterUnknownHashes`].
|
||||
///
|
||||
/// Inner value is the list of hashes that were in the main chain.
|
||||
FilterUnknownHashes(HashSet<[u8; 32]>),
|
||||
|
||||
/// Response to [`BCReadRequest::BlockExtendedHeaderInRange`].
|
||||
///
|
||||
/// Inner value is the list of extended header(s) of the requested block(s).
|
||||
BlockExtendedHeaderInRange(Vec<ExtendedBlockHeader>),
|
||||
|
||||
/// Response to [`ReadRequest::ChainHeight`].
|
||||
/// Response to [`BCReadRequest::ChainHeight`].
|
||||
///
|
||||
/// Inner value is the chain height, and the top block's hash.
|
||||
ChainHeight(u64, [u8; 32]),
|
||||
|
||||
/// Response to [`ReadRequest::GeneratedCoins`].
|
||||
/// Response to [`BCReadRequest::GeneratedCoins`].
|
||||
///
|
||||
/// Inner value is the total amount of generated coins so far, in atomic units.
|
||||
GeneratedCoins(u64),
|
||||
|
||||
/// Response to [`ReadRequest::Outputs`].
|
||||
/// Response to [`BCReadRequest::Outputs`].
|
||||
///
|
||||
/// Inner value is all the outputs requested,
|
||||
/// associated with their amount and amount index.
|
||||
Outputs(HashMap<u64, HashMap<u64, OutputOnChain>>),
|
||||
|
||||
/// Response to [`ReadRequest::NumberOutputsWithAmount`].
|
||||
/// Response to [`BCReadRequest::NumberOutputsWithAmount`].
|
||||
///
|
||||
/// Inner value is a `HashMap` of all the outputs requested where:
|
||||
/// - Key = output amount
|
||||
/// - Value = count of outputs with the same amount
|
||||
NumberOutputsWithAmount(HashMap<u64, usize>),
|
||||
|
||||
/// Response to [`ReadRequest::CheckKIsNotSpent`].
|
||||
/// Response to [`BCReadRequest::KeyImagesSpent`].
|
||||
///
|
||||
/// The inner value is `true` if _any_ of the key images
|
||||
/// were spent (exited in the database already).
|
||||
/// were spent (existed in the database already).
|
||||
///
|
||||
/// The inner value is `false` if _none_ of the key images were spent.
|
||||
CheckKIsNotSpent(bool),
|
||||
KeyImagesSpent(bool),
|
||||
|
||||
//------------------------------------------------------ Writes
|
||||
/// Response to [`WriteRequest::WriteBlock`].
|
||||
/// Response to [`BCWriteRequest::WriteBlock`].
|
||||
///
|
||||
/// This response indicates that the requested block has
|
||||
/// successfully been written to the database without error.
|
||||
|
|
|
@ -21,8 +21,6 @@ use serde::{Deserialize, Serialize};
|
|||
///
|
||||
/// For more definitions, see also: <https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_last_block_header>.
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
pub struct ExtendedBlockHeader {
|
||||
/// The block's major version.
|
||||
///
|
||||
|
@ -52,8 +50,6 @@ pub struct ExtendedBlockHeader {
|
|||
/// This represents data that allows verification of a transaction,
|
||||
/// although it doesn't mean it _has_ been verified.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // FIXME: monero_serai
|
||||
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
pub struct TransactionVerificationData {
|
||||
/// The transaction itself.
|
||||
pub tx: Transaction,
|
||||
|
@ -111,9 +107,7 @@ pub struct VerifiedBlockInformation {
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- OutputOnChain
|
||||
/// An already existing transaction output.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // FIXME: monero_serai
|
||||
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct OutputOnChain {
|
||||
/// The block height this output belongs to.
|
||||
pub height: u64,
|
||||
|
|
Loading…
Reference in a new issue