mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-26 12:26:12 +00:00
update monero-serai
This commit is contained in:
parent
7e9891de5b
commit
075e9b15cb
23 changed files with 411 additions and 413 deletions
278
Cargo.lock
generated
278
Cargo.lock
generated
|
@ -56,17 +56,6 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.5"
|
||||
|
@ -121,28 +110,12 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base58-monero"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978e81a45367d2409ecd33369a45dda2e9a3ca516153ec194de1fbda4b9fb79d"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
|
@ -343,15 +316,6 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
@ -433,12 +397,6 @@ version = "0.8.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
|
@ -523,12 +481,10 @@ dependencies = [
|
|||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"futures",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-serai",
|
||||
"multiexp",
|
||||
"proptest",
|
||||
"proptest-derive",
|
||||
"randomx-rs",
|
||||
|
@ -549,11 +505,9 @@ dependencies = [
|
|||
"cuprate-cryptonight",
|
||||
"cuprate-helper",
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-serai",
|
||||
"multiexp",
|
||||
"proptest",
|
||||
"proptest-derive",
|
||||
"rand",
|
||||
|
@ -772,7 +726,9 @@ dependencies = [
|
|||
"futures",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-rpc",
|
||||
"monero-serai",
|
||||
"monero-simple-request-rpc",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -838,7 +794,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "dalek-ff-group"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"crypto-bigint",
|
||||
"curve25519-dalek",
|
||||
|
@ -957,27 +913,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener-strategy"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
|
@ -1004,7 +939,7 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
|||
[[package]]
|
||||
name = "flexible-transcript"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"digest",
|
||||
|
@ -1238,15 +1173,6 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.1.0"
|
||||
|
@ -1283,9 +1209,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.9.3"
|
||||
version = "1.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545"
|
||||
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
|
@ -1656,63 +1582,151 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-borromean"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"monero-generators",
|
||||
"monero-io",
|
||||
"monero-primitives",
|
||||
"std-shims",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-bulletproofs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"monero-generators",
|
||||
"monero-io",
|
||||
"monero-primitives",
|
||||
"rand_core",
|
||||
"std-shims",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-clsag"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"flexible-transcript",
|
||||
"group",
|
||||
"monero-generators",
|
||||
"monero-io",
|
||||
"monero-primitives",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"std-shims",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-generators"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"group",
|
||||
"monero-io",
|
||||
"sha3",
|
||||
"std-shims",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-io"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"std-shims",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-mlsag"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"monero-generators",
|
||||
"monero-io",
|
||||
"monero-primitives",
|
||||
"std-shims",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-primitives"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"monero-generators",
|
||||
"monero-io",
|
||||
"sha3",
|
||||
"std-shims",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-rpc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"curve25519-dalek",
|
||||
"hex",
|
||||
"monero-serai",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"std-shims",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monero-serai"
|
||||
version = "0.1.4-alpha"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"async-trait",
|
||||
"base58-monero",
|
||||
"curve25519-dalek",
|
||||
"dalek-ff-group",
|
||||
"digest_auth",
|
||||
"flexible-transcript",
|
||||
"group",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-borromean",
|
||||
"monero-bulletproofs",
|
||||
"monero-clsag",
|
||||
"monero-generators",
|
||||
"multiexp",
|
||||
"pbkdf2",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"monero-io",
|
||||
"monero-mlsag",
|
||||
"monero-primitives",
|
||||
"rand_core",
|
||||
"rand_distr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha3",
|
||||
"simple-request",
|
||||
"std-shims",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multiexp"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
name = "monero-simple-request-rpc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"group",
|
||||
"rand_core",
|
||||
"rustversion",
|
||||
"std-shims",
|
||||
"zeroize",
|
||||
"async-trait",
|
||||
"digest_auth",
|
||||
"hex",
|
||||
"monero-rpc",
|
||||
"simple-request",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1772,12 +1786,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
|
@ -1801,35 +1809,12 @@ dependencies = [
|
|||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"hmac",
|
||||
"password-hash",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -2382,7 +2367,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "simple-request"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
|
@ -2438,7 +2423,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
|||
[[package]]
|
||||
name = "std-shims"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?rev=d27d934#d27d93480aa8a849d84214ad4c71d83ce6fea0c1"
|
||||
source = "git+https://github.com/Cuprate/serai.git?branch=monero-tidy#148137618a72c365b7e846a73292f01f53c0f941"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"spin",
|
||||
|
@ -2552,15 +2537,6 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.7.6"
|
||||
|
|
|
@ -57,15 +57,15 @@ chrono = { version = "0.4.31", 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.3", default-features = false }
|
||||
dalek-ff-group = { git = "https://github.com/Cuprate/serai.git", rev = "d27d934", 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 }
|
||||
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 }
|
||||
monero-rpc = { git = "https://github.com/Cuprate/serai.git", branch = "monero-tidy", default-features = false }
|
||||
monero-simple-request-rpc = { git = "https://github.com/Cuprate/serai.git", branch = "monero-tidy", default-features = false }
|
||||
monero-serai = { git = "https://github.com/Cuprate/serai.git", branch = "monero-tidy", default-features = false }
|
||||
paste = { version = "1.0.14", default-features = false }
|
||||
pin-project = { version = "1.1.3", default-features = false }
|
||||
randomx-rs = { git = "https://github.com/Cuprate/randomx-rs.git", rev = "0028464", default-features = false }
|
||||
|
|
|
@ -19,8 +19,6 @@ futures = { workspace = true, features = ["std", "async-await"] }
|
|||
|
||||
randomx-rs = { workspace = true }
|
||||
monero-serai = { workspace = true, features = ["std"] }
|
||||
multiexp = { workspace = true }
|
||||
dalek-ff-group = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
|
||||
rayon = { workspace = true }
|
||||
|
|
|
@ -244,7 +244,7 @@ where
|
|||
|
||||
let block_blob = block.serialize();
|
||||
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix.inputs.first() else {
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix().inputs.first() else {
|
||||
return Err(FastSyncError::MinerTx(MinerTxError::InputNotOfTypeGen));
|
||||
};
|
||||
if *height != block_chain_ctx.chain_height {
|
||||
|
@ -270,7 +270,7 @@ where
|
|||
let total_fees = verified_txs.iter().map(|tx| tx.fee).sum::<u64>();
|
||||
let total_outputs = block
|
||||
.miner_tx
|
||||
.prefix
|
||||
.prefix()
|
||||
.outputs
|
||||
.iter()
|
||||
.map(|output| output.amount.unwrap_or(0))
|
||||
|
|
|
@ -15,8 +15,6 @@ cuprate-helper = { path = "../../helper", default-features = false, features = [
|
|||
cuprate-cryptonight = {path = "../../cryptonight"}
|
||||
|
||||
monero-serai = { workspace = true, features = ["std"] }
|
||||
multiexp = { workspace = true, features = ["std", "batch"] }
|
||||
dalek-ff-group = { workspace = true, features = ["std"] }
|
||||
curve25519-dalek = { workspace = true, features = ["alloc", "zeroize", "precomputed-tables"] }
|
||||
|
||||
rand = { workspace = true, features = ["std", "std_rng"] }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use multiexp::BatchVerifier as InternalBatchVerifier;
|
||||
use monero_serai::ringct::bulletproofs::BatchVerifier as InternalBatchVerifier;
|
||||
|
||||
/// This trait represents a batch verifier.
|
||||
///
|
||||
|
@ -12,18 +12,12 @@ pub trait BatchVerifier {
|
|||
/// # Panics
|
||||
/// This function may panic if `stmt` contains calls to `rayon`'s parallel iterators, e.g. `par_iter()`.
|
||||
// TODO: remove the panics by adding a generic API upstream.
|
||||
fn queue_statement<R>(
|
||||
&mut self,
|
||||
stmt: impl FnOnce(&mut InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>) -> R,
|
||||
) -> R;
|
||||
fn queue_statement<R>(&mut self, stmt: impl FnOnce(&mut InternalBatchVerifier) -> R) -> R;
|
||||
}
|
||||
|
||||
// impl this for a single threaded batch verifier.
|
||||
impl BatchVerifier for &'_ mut InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint> {
|
||||
fn queue_statement<R>(
|
||||
&mut self,
|
||||
stmt: impl FnOnce(&mut InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>) -> R,
|
||||
) -> R {
|
||||
impl BatchVerifier for &'_ mut InternalBatchVerifier {
|
||||
fn queue_statement<R>(&mut self, stmt: impl FnOnce(&mut InternalBatchVerifier) -> R) -> R {
|
||||
stmt(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ fn genesis_miner_tx(network: &Network) -> Transaction {
|
|||
pub fn generate_genesis_block(network: &Network) -> Block {
|
||||
Block {
|
||||
header: BlockHeader {
|
||||
major_version: 1,
|
||||
minor_version: 0,
|
||||
hardfork_version: 1,
|
||||
hardfork_signal: 0,
|
||||
timestamp: 0,
|
||||
previous: [0; 32],
|
||||
nonce: genesis_nonce(network),
|
||||
|
|
|
@ -202,8 +202,8 @@ impl HardFork {
|
|||
#[inline]
|
||||
pub fn from_block_header(header: &BlockHeader) -> Result<(HardFork, HardFork), HardForkError> {
|
||||
Ok((
|
||||
HardFork::from_version(header.major_version)?,
|
||||
HardFork::from_vote(header.minor_version),
|
||||
HardFork::from_version(header.hardfork_version)?,
|
||||
HardFork::from_vote(header.hardfork_signal),
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use monero_serai::{
|
||||
ringct::RctType,
|
||||
transaction::{Input, Output, Timelock, Transaction},
|
||||
};
|
||||
use monero_serai::transaction::{Input, Output, Timelock, Transaction};
|
||||
|
||||
use crate::{is_decomposed_amount, transactions::check_output_types, HardFork, TxVersion};
|
||||
|
||||
|
@ -188,22 +185,27 @@ pub fn check_miner_tx(
|
|||
already_generated_coins: u64,
|
||||
hf: &HardFork,
|
||||
) -> Result<u64, MinerTxError> {
|
||||
let tx_version = TxVersion::from_raw(tx.prefix.version).ok_or(MinerTxError::VersionInvalid)?;
|
||||
let tx_version = TxVersion::from_raw(tx.version()).ok_or(MinerTxError::VersionInvalid)?;
|
||||
check_miner_tx_version(&tx_version, hf)?;
|
||||
|
||||
// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/miner_tx.html#ringct-type>
|
||||
if hf >= &HardFork::V12 && tx.rct_signatures.rct_type() != RctType::Null {
|
||||
return Err(MinerTxError::RCTTypeNotNULL);
|
||||
match tx {
|
||||
Transaction::V1 { .. } => (),
|
||||
Transaction::V2 { proofs, .. } => {
|
||||
if hf >= &HardFork::V12 && proofs.is_some() {
|
||||
return Err(MinerTxError::RCTTypeNotNULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_time_lock(&tx.prefix.timelock, chain_height)?;
|
||||
check_time_lock(&tx.prefix().timelock, chain_height)?;
|
||||
|
||||
check_inputs(&tx.prefix.inputs, chain_height)?;
|
||||
check_inputs(&tx.prefix().inputs, chain_height)?;
|
||||
|
||||
check_output_types(&tx.prefix.outputs, hf).map_err(|_| MinerTxError::InvalidOutputType)?;
|
||||
check_output_types(&tx.prefix().outputs, hf).map_err(|_| MinerTxError::InvalidOutputType)?;
|
||||
|
||||
let reward = calculate_block_reward(block_weight, median_bw, already_generated_coins, hf);
|
||||
let total_outs = sum_outputs(&tx.prefix.outputs, hf, &tx_version)?;
|
||||
let total_outs = sum_outputs(&tx.prefix().outputs, hf, &tx_version)?;
|
||||
|
||||
check_total_output_amt(total_outs, reward, total_fees, hf)
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ impl TxVersion {
|
|||
///
|
||||
/// ref: <https://monero-book.cuprate.org/consensus_rules/transactions.html#version>
|
||||
/// && <https://monero-book.cuprate.org/consensus_rules/blocks/miner_tx.html#version>
|
||||
pub fn from_raw(version: u64) -> Option<TxVersion> {
|
||||
pub fn from_raw(version: u8) -> Option<TxVersion> {
|
||||
Some(match version {
|
||||
1 => TxVersion::RingSignatures,
|
||||
2 => TxVersion::RingCT,
|
||||
|
@ -205,7 +205,7 @@ fn check_number_of_outputs(
|
|||
outputs: usize,
|
||||
hf: &HardFork,
|
||||
tx_version: &TxVersion,
|
||||
rct_type: &RctType,
|
||||
bp_or_bpp: bool,
|
||||
) -> Result<(), TransactionError> {
|
||||
if tx_version == &TxVersion::RingSignatures {
|
||||
return Ok(());
|
||||
|
@ -215,18 +215,10 @@ fn check_number_of_outputs(
|
|||
return Err(TransactionError::InvalidNumberOfOutputs);
|
||||
}
|
||||
|
||||
match rct_type {
|
||||
RctType::Bulletproofs
|
||||
| RctType::BulletproofsCompactAmount
|
||||
| RctType::Clsag
|
||||
| RctType::BulletproofsPlus => {
|
||||
if outputs <= MAX_BULLETPROOFS_OUTPUTS {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TransactionError::InvalidNumberOfOutputs)
|
||||
}
|
||||
}
|
||||
_ => Ok(()),
|
||||
if bp_or_bpp && outputs > MAX_BULLETPROOFS_OUTPUTS {
|
||||
Err(TransactionError::InvalidNumberOfOutputs)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,11 +231,11 @@ fn check_outputs_semantics(
|
|||
outputs: &[Output],
|
||||
hf: &HardFork,
|
||||
tx_version: &TxVersion,
|
||||
rct_type: &RctType,
|
||||
bp_or_bpp: bool,
|
||||
) -> Result<u64, TransactionError> {
|
||||
check_output_types(outputs, hf)?;
|
||||
check_output_keys(outputs)?;
|
||||
check_number_of_outputs(outputs.len(), hf, tx_version, rct_type)?;
|
||||
check_number_of_outputs(outputs.len(), hf, tx_version, bp_or_bpp)?;
|
||||
|
||||
sum_outputs(outputs, hf, tx_version)
|
||||
}
|
||||
|
@ -615,28 +607,41 @@ pub fn check_transaction_semantic(
|
|||
Err(TransactionError::TooBig)?;
|
||||
}
|
||||
|
||||
let tx_version = TxVersion::from_raw(tx.prefix.version)
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?;
|
||||
let tx_version =
|
||||
TxVersion::from_raw(tx.version()).ok_or(TransactionError::TransactionVersionInvalid)?;
|
||||
|
||||
let outputs_sum = check_outputs_semantics(
|
||||
&tx.prefix.outputs,
|
||||
hf,
|
||||
&tx_version,
|
||||
&tx.rct_signatures.rct_type(),
|
||||
)?;
|
||||
let inputs_sum = check_inputs_semantics(&tx.prefix.inputs, hf)?;
|
||||
let bp_or_bpp = match tx {
|
||||
Transaction::V2 {
|
||||
proofs: Some(proofs),
|
||||
..
|
||||
} => match proofs.rct_type() {
|
||||
RctType::AggregateMlsagBorromean | RctType::MlsagBorromean => false,
|
||||
RctType::MlsagBulletproofs
|
||||
| RctType::MlsagBulletproofsCompactAmount
|
||||
| RctType::ClsagBulletproof
|
||||
| RctType::ClsagBulletproofPlus => true,
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let fee = match tx_version {
|
||||
TxVersion::RingSignatures => {
|
||||
let outputs_sum = check_outputs_semantics(&tx.prefix().outputs, hf, &tx_version, bp_or_bpp)?;
|
||||
let inputs_sum = check_inputs_semantics(&tx.prefix().inputs, hf)?;
|
||||
|
||||
let fee = match tx {
|
||||
Transaction::V1 { .. } => {
|
||||
if outputs_sum >= inputs_sum {
|
||||
Err(TransactionError::OutputsTooHigh)?;
|
||||
}
|
||||
inputs_sum - outputs_sum
|
||||
}
|
||||
TxVersion::RingCT => {
|
||||
ring_ct::ring_ct_semantic_checks(tx, tx_hash, verifier, hf)?;
|
||||
Transaction::V2 { proofs, .. } => {
|
||||
let proofs = proofs
|
||||
.as_ref()
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?;
|
||||
|
||||
tx.rct_signatures.base.fee
|
||||
ring_ct::ring_ct_semantic_checks(proofs, tx_hash, verifier, hf)?;
|
||||
|
||||
proofs.base.fee
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -658,11 +663,11 @@ pub fn check_transaction_contextual(
|
|||
current_time_lock_timestamp: u64,
|
||||
hf: &HardFork,
|
||||
) -> Result<(), TransactionError> {
|
||||
let tx_version = TxVersion::from_raw(tx.prefix.version)
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?;
|
||||
let tx_version =
|
||||
TxVersion::from_raw(tx.version()).ok_or(TransactionError::TransactionVersionInvalid)?;
|
||||
|
||||
check_inputs_contextual(
|
||||
&tx.prefix.inputs,
|
||||
&tx.prefix().inputs,
|
||||
tx_ring_members_info,
|
||||
current_chain_height,
|
||||
hf,
|
||||
|
@ -676,17 +681,22 @@ pub fn check_transaction_contextual(
|
|||
hf,
|
||||
)?;
|
||||
|
||||
match tx_version {
|
||||
TxVersion::RingSignatures => ring_signatures::check_input_signatures(
|
||||
&tx.prefix.inputs,
|
||||
&tx.signatures,
|
||||
match &tx {
|
||||
Transaction::V1 { prefix, signatures } => ring_signatures::check_input_signatures(
|
||||
&prefix.inputs,
|
||||
signatures,
|
||||
&tx_ring_members_info.rings,
|
||||
&tx.signature_hash(),
|
||||
// This will only return None on v2 miner txs.
|
||||
&tx.signature_hash()
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?,
|
||||
),
|
||||
TxVersion::RingCT => Ok(ring_ct::check_input_signatures(
|
||||
&tx.signature_hash(),
|
||||
&tx.prefix.inputs,
|
||||
&tx.rct_signatures,
|
||||
Transaction::V2 { prefix, proofs } => Ok(ring_ct::check_input_signatures(
|
||||
&tx.signature_hash()
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?,
|
||||
&prefix.inputs,
|
||||
proofs
|
||||
.as_ref()
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?,
|
||||
&tx_ring_members_info.rings,
|
||||
)?),
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use curve25519_dalek::{EdwardsPoint, Scalar};
|
||||
use hex_literal::hex;
|
||||
use monero_serai::{
|
||||
generators::H,
|
||||
ringct::{
|
||||
clsag::ClsagError,
|
||||
mlsag::{AggregateRingMatrixBuilder, MlsagError, RingMatrix},
|
||||
RctPrunable, RctSignatures, RctType,
|
||||
RctProofs, RctPrunable, RctType,
|
||||
},
|
||||
transaction::{Input, Transaction},
|
||||
H,
|
||||
transaction::Input,
|
||||
};
|
||||
use rand::thread_rng;
|
||||
#[cfg(feature = "rayon")]
|
||||
|
@ -48,12 +48,12 @@ fn check_rct_type(ty: &RctType, hf: HardFork, tx_hash: &[u8; 32]) -> Result<(),
|
|||
use RctType as T;
|
||||
|
||||
match ty {
|
||||
T::MlsagAggregate | T::MlsagIndividual if hf >= F::V4 && hf < F::V9 => Ok(()),
|
||||
T::Bulletproofs if hf >= F::V8 && hf < F::V11 => Ok(()),
|
||||
T::BulletproofsCompactAmount if hf >= F::V10 && hf < F::V14 => Ok(()),
|
||||
T::BulletproofsCompactAmount if GRANDFATHERED_TRANSACTIONS.contains(tx_hash) => Ok(()),
|
||||
T::Clsag if hf >= F::V13 && hf < F::V16 => Ok(()),
|
||||
T::BulletproofsPlus if hf >= F::V15 => Ok(()),
|
||||
T::AggregateMlsagBorromean | T::MlsagBorromean if hf >= F::V4 && hf < F::V9 => Ok(()),
|
||||
T::MlsagBulletproofs if hf >= F::V8 && hf < F::V11 => Ok(()),
|
||||
T::MlsagBulletproofsCompactAmount if hf >= F::V10 && hf < F::V14 => Ok(()),
|
||||
T::MlsagBulletproofsCompactAmount if GRANDFATHERED_TRANSACTIONS.contains(tx_hash) => Ok(()),
|
||||
T::ClsagBulletproof if hf >= F::V13 && hf < F::V16 => Ok(()),
|
||||
T::ClsagBulletproofPlus if hf >= F::V15 => Ok(()),
|
||||
_ => Err(RingCTError::TypeNotAllowed),
|
||||
}
|
||||
}
|
||||
|
@ -61,14 +61,16 @@ fn check_rct_type(ty: &RctType, hf: HardFork, tx_hash: &[u8; 32]) -> Result<(),
|
|||
/// Checks that the pseudo-outs sum to the same point as the output commitments.
|
||||
///
|
||||
/// <https://monero-book.cuprate.org/consensus_rules/ring_ct.html#pseudo-outs-outpks-balance>
|
||||
fn simple_type_balances(rct_sig: &RctSignatures) -> Result<(), RingCTError> {
|
||||
let pseudo_outs = if rct_sig.rct_type() == RctType::MlsagIndividual {
|
||||
fn simple_type_balances(rct_sig: &RctProofs) -> Result<(), RingCTError> {
|
||||
let pseudo_outs = if rct_sig.rct_type() == RctType::MlsagBorromean {
|
||||
&rct_sig.base.pseudo_outs
|
||||
} else {
|
||||
match &rct_sig.prunable {
|
||||
RctPrunable::Clsag { pseudo_outs, .. }
|
||||
| RctPrunable::MlsagBulletproofsCompactAmount { pseudo_outs, .. }
|
||||
| RctPrunable::MlsagBulletproofs { pseudo_outs, .. } => pseudo_outs,
|
||||
_ => panic!("RingCT type is not simple!"),
|
||||
RctPrunable::MlsagBorromean { .. } => &rct_sig.base.pseudo_outs,
|
||||
RctPrunable::AggregateMlsagBorromean { .. } => panic!("RingCT type is not simple!"),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -89,13 +91,12 @@ fn simple_type_balances(rct_sig: &RctSignatures) -> Result<(), RingCTError> {
|
|||
/// <https://monero-book.cuprate.org/consensus_rules/ring_ct/bulletproofs.html>
|
||||
/// <https://monero-book.cuprate.org/consensus_rules/ring_ct/bulletproofs+.html>
|
||||
fn check_output_range_proofs(
|
||||
rct_sig: &RctSignatures,
|
||||
proofs: &RctProofs,
|
||||
mut verifier: impl BatchVerifier,
|
||||
) -> Result<(), RingCTError> {
|
||||
let commitments = &rct_sig.base.commitments;
|
||||
let commitments = &proofs.base.commitments;
|
||||
|
||||
match &rct_sig.prunable {
|
||||
RctPrunable::Null => Err(RingCTError::TypeNotAllowed)?,
|
||||
match &proofs.prunable {
|
||||
RctPrunable::MlsagBorromean { borromean, .. }
|
||||
| RctPrunable::AggregateMlsagBorromean { borromean, .. } => try_par_iter(borromean)
|
||||
.zip(commitments)
|
||||
|
@ -106,10 +107,11 @@ fn check_output_range_proofs(
|
|||
Err(RingCTError::BorromeanRangeInvalid)
|
||||
}
|
||||
}),
|
||||
RctPrunable::MlsagBulletproofs { bulletproofs, .. }
|
||||
| RctPrunable::Clsag { bulletproofs, .. } => {
|
||||
RctPrunable::MlsagBulletproofs { bulletproof, .. }
|
||||
| RctPrunable::MlsagBulletproofsCompactAmount { bulletproof, .. }
|
||||
| RctPrunable::Clsag { bulletproof, .. } => {
|
||||
if verifier.queue_statement(|verifier| {
|
||||
bulletproofs.batch_verify(&mut thread_rng(), verifier, (), commitments)
|
||||
bulletproof.batch_verify(&mut thread_rng(), verifier, commitments)
|
||||
}) {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -120,18 +122,18 @@ fn check_output_range_proofs(
|
|||
}
|
||||
|
||||
pub(crate) fn ring_ct_semantic_checks(
|
||||
tx: &Transaction,
|
||||
proofs: &RctProofs,
|
||||
tx_hash: &[u8; 32],
|
||||
verifier: impl BatchVerifier,
|
||||
hf: &HardFork,
|
||||
) -> Result<(), RingCTError> {
|
||||
let rct_type = tx.rct_signatures.rct_type();
|
||||
let rct_type = proofs.rct_type();
|
||||
|
||||
check_rct_type(&rct_type, *hf, tx_hash)?;
|
||||
check_output_range_proofs(&tx.rct_signatures, verifier)?;
|
||||
check_output_range_proofs(&proofs, verifier)?;
|
||||
|
||||
if rct_type != RctType::MlsagAggregate {
|
||||
simple_type_balances(&tx.rct_signatures)?;
|
||||
if rct_type != RctType::AggregateMlsagBorromean {
|
||||
simple_type_balances(&proofs)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -144,7 +146,7 @@ pub(crate) fn ring_ct_semantic_checks(
|
|||
pub(crate) fn check_input_signatures(
|
||||
msg: &[u8; 32],
|
||||
inputs: &[Input],
|
||||
rct_sig: &RctSignatures,
|
||||
proofs: &RctProofs,
|
||||
rings: &Rings,
|
||||
) -> Result<(), RingCTError> {
|
||||
let Rings::RingCT(rings) = rings else {
|
||||
|
@ -155,15 +157,15 @@ pub(crate) fn check_input_signatures(
|
|||
Err(RingCTError::RingInvalid)?;
|
||||
}
|
||||
|
||||
let pseudo_outs = match &rct_sig.prunable {
|
||||
let pseudo_outs = match &proofs.prunable {
|
||||
RctPrunable::MlsagBulletproofs { pseudo_outs, .. }
|
||||
| RctPrunable::MlsagBulletproofsCompactAmount { pseudo_outs, .. }
|
||||
| RctPrunable::Clsag { pseudo_outs, .. } => pseudo_outs.as_slice(),
|
||||
RctPrunable::MlsagBorromean { .. } => rct_sig.base.pseudo_outs.as_slice(),
|
||||
RctPrunable::AggregateMlsagBorromean { .. } | RctPrunable::Null => &[],
|
||||
RctPrunable::MlsagBorromean { .. } => proofs.base.pseudo_outs.as_slice(),
|
||||
RctPrunable::AggregateMlsagBorromean { .. } => &[],
|
||||
};
|
||||
|
||||
match &rct_sig.prunable {
|
||||
RctPrunable::Null => Err(RingCTError::TypeNotAllowed)?,
|
||||
match &proofs.prunable {
|
||||
RctPrunable::AggregateMlsagBorromean { mlsag, .. } => {
|
||||
let key_images = inputs
|
||||
.iter()
|
||||
|
@ -176,11 +178,14 @@ pub(crate) fn check_input_signatures(
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
let mut matrix =
|
||||
AggregateRingMatrixBuilder::new(&rct_sig.base.commitments, rct_sig.base.fee);
|
||||
AggregateRingMatrixBuilder::new(&proofs.base.commitments, proofs.base.fee);
|
||||
|
||||
rings.iter().try_for_each(|ring| matrix.push_ring(ring))?;
|
||||
|
||||
Ok(mlsag.verify(msg, &matrix.build()?, &key_images)?)
|
||||
}
|
||||
RctPrunable::MlsagBorromean { mlsags, .. }
|
||||
| RctPrunable::MlsagBulletproofsCompactAmount { mlsags, .. }
|
||||
| RctPrunable::MlsagBulletproofs { mlsags, .. } => try_par_iter(mlsags)
|
||||
.zip(pseudo_outs)
|
||||
.zip(inputs)
|
||||
|
@ -216,18 +221,21 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn grandfathered_bulletproofs2() {
|
||||
assert!(
|
||||
check_rct_type(&RctType::BulletproofsCompactAmount, HardFork::V14, &[0; 32]).is_err()
|
||||
);
|
||||
assert!(check_rct_type(
|
||||
&RctType::MlsagBulletproofsCompactAmount,
|
||||
HardFork::V14,
|
||||
&[0; 32]
|
||||
)
|
||||
.is_err());
|
||||
|
||||
assert!(check_rct_type(
|
||||
&RctType::BulletproofsCompactAmount,
|
||||
&RctType::MlsagBulletproofsCompactAmount,
|
||||
HardFork::V14,
|
||||
&GRANDFATHERED_TRANSACTIONS[0]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(check_rct_type(
|
||||
&RctType::BulletproofsCompactAmount,
|
||||
&RctType::MlsagBulletproofsCompactAmount,
|
||||
HardFork::V14,
|
||||
&GRANDFATHERED_TRANSACTIONS[1]
|
||||
)
|
||||
|
|
|
@ -97,31 +97,6 @@ fn test_torsion_ki() {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a strategy that resolves to a [`RctType`] that uses
|
||||
/// BPs(+).
|
||||
#[allow(unreachable_code)]
|
||||
#[allow(clippy::diverging_sub_expression)]
|
||||
fn bulletproof_rct_type() -> BoxedStrategy<RctType> {
|
||||
return prop_oneof![
|
||||
Just(RctType::Bulletproofs),
|
||||
Just(RctType::BulletproofsCompactAmount),
|
||||
Just(RctType::Clsag),
|
||||
Just(RctType::BulletproofsPlus),
|
||||
]
|
||||
.boxed();
|
||||
|
||||
// Here to make sure this is updated when needed.
|
||||
match unreachable!() {
|
||||
RctType::Null => {}
|
||||
RctType::MlsagAggregate => {}
|
||||
RctType::MlsagIndividual => {}
|
||||
RctType::Bulletproofs => {}
|
||||
RctType::BulletproofsCompactAmount => {}
|
||||
RctType::Clsag => {}
|
||||
RctType::BulletproofsPlus => {}
|
||||
};
|
||||
}
|
||||
|
||||
prop_compose! {
|
||||
/// Returns a valid prime-order point.
|
||||
fn random_point()(bytes in any::<[u8; 32]>()) -> EdwardsPoint {
|
||||
|
@ -240,13 +215,13 @@ proptest! {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_valid_number_of_outputs(valid_numb_outs in 2..17_usize, rct_type in bulletproof_rct_type()) {
|
||||
prop_assert!(check_number_of_outputs(valid_numb_outs, &HardFork::V16, &TxVersion::RingCT, &rct_type).is_ok());
|
||||
fn test_valid_number_of_outputs(valid_numb_outs in 2..17_usize) {
|
||||
prop_assert!(check_number_of_outputs(valid_numb_outs, &HardFork::V16, &TxVersion::RingCT, true).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_number_of_outputs(numb_outs in 17..usize::MAX, rct_type in bulletproof_rct_type()) {
|
||||
prop_assert!(check_number_of_outputs(numb_outs, &HardFork::V16, &TxVersion::RingCT, &rct_type).is_err());
|
||||
fn test_invalid_number_of_outputs(numb_outs in 17..usize::MAX) {
|
||||
prop_assert!(check_number_of_outputs(numb_outs, &HardFork::V16, &TxVersion::RingCT, true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use std::{cell::RefCell, ops::DerefMut};
|
||||
|
||||
use multiexp::BatchVerifier as InternalBatchVerifier;
|
||||
use monero_serai::ringct::bulletproofs::BatchVerifier as InternalBatchVerifier;
|
||||
use rayon::prelude::*;
|
||||
use thread_local::ThreadLocal;
|
||||
|
||||
use cuprate_consensus_rules::batch_verifier::BatchVerifier;
|
||||
|
||||
/// A multithreaded batch verifier.
|
||||
pub struct MultiThreadedBatchVerifier {
|
||||
internal: ThreadLocal<RefCell<InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>>>,
|
||||
internal: ThreadLocal<RefCell<InternalBatchVerifier>>,
|
||||
}
|
||||
|
||||
impl MultiThreadedBatchVerifier {
|
||||
|
@ -22,19 +24,22 @@ impl MultiThreadedBatchVerifier {
|
|||
.into_iter()
|
||||
.map(RefCell::into_inner)
|
||||
.par_bridge()
|
||||
.find_any(|batch_verifier| !batch_verifier.verify_vartime())
|
||||
.is_none()
|
||||
.try_for_each(|batch_verifier| {
|
||||
if batch_verifier.verify() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
})
|
||||
.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl cuprate_consensus_rules::batch_verifier::BatchVerifier for &'_ MultiThreadedBatchVerifier {
|
||||
fn queue_statement<R>(
|
||||
&mut self,
|
||||
stmt: impl FnOnce(&mut InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>) -> R,
|
||||
) -> R {
|
||||
impl BatchVerifier for &'_ MultiThreadedBatchVerifier {
|
||||
fn queue_statement<R>(&mut self, stmt: impl FnOnce(&mut InternalBatchVerifier) -> R) -> R {
|
||||
let mut verifier = self
|
||||
.internal
|
||||
.get_or(|| RefCell::new(InternalBatchVerifier::new(32)))
|
||||
.get_or(|| RefCell::new(InternalBatchVerifier::new()))
|
||||
.borrow_mut();
|
||||
|
||||
stmt(verifier.deref_mut())
|
||||
|
|
|
@ -70,7 +70,7 @@ impl PreparedBlockExPow {
|
|||
let (hf_version, hf_vote) =
|
||||
HardFork::from_block_header(&block.header).map_err(BlockError::HardForkError)?;
|
||||
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix.inputs.first() else {
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix().inputs.first() else {
|
||||
Err(ConsensusError::Block(BlockError::MinerTxError(
|
||||
MinerTxError::InputNotOfTypeGen,
|
||||
)))?
|
||||
|
@ -124,7 +124,7 @@ impl PreparedBlock {
|
|||
let (hf_version, hf_vote) =
|
||||
HardFork::from_block_header(&block.header).map_err(BlockError::HardForkError)?;
|
||||
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix.inputs.first() else {
|
||||
let Some(Input::Gen(height)) = block.miner_tx.prefix().inputs.first() else {
|
||||
Err(ConsensusError::Block(BlockError::MinerTxError(
|
||||
MinerTxError::InputNotOfTypeGen,
|
||||
)))?
|
||||
|
@ -138,7 +138,7 @@ impl PreparedBlock {
|
|||
block_hash: block.hash(),
|
||||
pow_hash: calculate_pow_hash(
|
||||
randomx_vm,
|
||||
&block.serialize_hashable(),
|
||||
&block.serialize_pow_hash(),
|
||||
*height,
|
||||
&hf_version,
|
||||
)?,
|
||||
|
@ -168,7 +168,7 @@ impl PreparedBlock {
|
|||
block_hash: block.block_hash,
|
||||
pow_hash: calculate_pow_hash(
|
||||
randomx_vm,
|
||||
&block.block.serialize_hashable(),
|
||||
&block.block.serialize_pow_hash(),
|
||||
block.height,
|
||||
&block.hf_version,
|
||||
)?,
|
||||
|
@ -527,9 +527,8 @@ where
|
|||
);
|
||||
|
||||
// Set up the block and just pass it to [`verify_prepped_main_chain_block`]
|
||||
|
||||
// We just use the raw `major_version` here, no need to turn it into a `HardFork`.
|
||||
let rx_vms = if block.header.major_version < 12 {
|
||||
// We just use the raw `hardfork_version` here, no need to turn it into a `HardFork`.
|
||||
let rx_vms = if block.header.hardfork_version < 12 {
|
||||
HashMap::new()
|
||||
} else {
|
||||
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
||||
|
|
|
@ -12,6 +12,7 @@ use std::{
|
|||
};
|
||||
|
||||
use futures::FutureExt;
|
||||
use monero_serai::ringct::bulletproofs::Bulletproof;
|
||||
use monero_serai::{
|
||||
ringct::RctType,
|
||||
transaction::{Input, Timelock, Transaction},
|
||||
|
@ -104,21 +105,62 @@ impl TransactionVerificationData {
|
|||
let tx_blob = tx.serialize();
|
||||
|
||||
// the tx weight is only different from the blobs length for bp(+) txs.
|
||||
let tx_weight = match tx.rct_signatures.rct_type() {
|
||||
RctType::Bulletproofs
|
||||
| RctType::BulletproofsCompactAmount
|
||||
| RctType::Clsag
|
||||
| RctType::BulletproofsPlus => tx.weight(),
|
||||
_ => tx_blob.len(),
|
||||
let tx_weight = match &tx {
|
||||
Transaction::V1 { .. } | Transaction::V2 { proofs: None, .. } => tx_blob.len(),
|
||||
Transaction::V2 {
|
||||
proofs: Some(proofs),
|
||||
..
|
||||
} => match proofs.rct_type() {
|
||||
RctType::AggregateMlsagBorromean | RctType::MlsagBorromean => tx_blob.len(),
|
||||
RctType::MlsagBulletproofs
|
||||
| RctType::MlsagBulletproofsCompactAmount
|
||||
| RctType::ClsagBulletproof => {
|
||||
tx_blob.len()
|
||||
+ Bulletproof::calculate_bp_clawback(false, tx.prefix().outputs.len()).0
|
||||
}
|
||||
RctType::ClsagBulletproofPlus => {
|
||||
tx_blob.len()
|
||||
+ Bulletproof::calculate_bp_clawback(true, tx.prefix().outputs.len()).0
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let mut fee = 0_u64;
|
||||
|
||||
match &tx {
|
||||
Transaction::V1 { prefix, .. } => {
|
||||
for input in &prefix.inputs {
|
||||
match input {
|
||||
Input::ToKey { amount, .. } => {
|
||||
fee = fee
|
||||
.checked_add(amount.unwrap_or(0))
|
||||
.ok_or(TransactionError::InputsOverflow)?;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
for output in &prefix.outputs {
|
||||
fee.checked_sub(output.amount.unwrap_or(0))
|
||||
.ok_or(TransactionError::OutputsTooHigh)?;
|
||||
}
|
||||
}
|
||||
Transaction::V2 { proofs, .. } => {
|
||||
fee = proofs
|
||||
.as_ref()
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?
|
||||
.base
|
||||
.fee;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(TransactionVerificationData {
|
||||
tx_hash,
|
||||
tx_blob,
|
||||
tx_weight,
|
||||
fee: tx.rct_signatures.base.fee,
|
||||
fee,
|
||||
cached_verification_state: StdMutex::new(CachedVerificationState::NotVerified),
|
||||
version: TxVersion::from_raw(tx.prefix.version)
|
||||
version: TxVersion::from_raw(tx.version())
|
||||
.ok_or(TransactionError::TransactionVersionInvalid)?,
|
||||
tx,
|
||||
})
|
||||
|
@ -296,7 +338,7 @@ where
|
|||
let mut spent_kis = HashSet::with_capacity(txs.len());
|
||||
|
||||
txs.iter().try_for_each(|tx| {
|
||||
tx.tx.prefix.inputs.iter().try_for_each(|input| {
|
||||
tx.tx.prefix().inputs.iter().try_for_each(|input| {
|
||||
if let Input::ToKey { key_image, .. } = input {
|
||||
if !spent_kis.insert(key_image.compress().0) {
|
||||
tracing::debug!("Duplicate key image found in batch.");
|
||||
|
@ -499,7 +541,7 @@ where
|
|||
&hf,
|
||||
&batch_verifier,
|
||||
)?;
|
||||
// make sure monero-serai calculated the same fee.
|
||||
// make sure we calculated the right fee.
|
||||
assert_eq!(fee, tx.fee);
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ pub async fn batch_get_ring_member_info<D: Database>(
|
|||
let mut output_ids = HashMap::new();
|
||||
|
||||
for tx_v_data in txs_verification_data.clone() {
|
||||
insert_ring_member_ids(&tx_v_data.tx.prefix.inputs, &mut output_ids)
|
||||
insert_ring_member_ids(&tx_v_data.tx.prefix().inputs, &mut output_ids)
|
||||
.map_err(ConsensusError::Transaction)?;
|
||||
}
|
||||
|
||||
|
@ -179,14 +179,14 @@ pub async fn batch_get_ring_member_info<D: Database>(
|
|||
|
||||
let ring_members_for_tx = get_ring_members_for_inputs(
|
||||
|amt, idx| outputs.get(&amt)?.get(&idx).copied(),
|
||||
&tx_v_data.tx.prefix.inputs,
|
||||
&tx_v_data.tx.prefix().inputs,
|
||||
)
|
||||
.map_err(ConsensusError::Transaction)?;
|
||||
|
||||
let decoy_info = if hf != &HardFork::V1 {
|
||||
// this data is only needed after hard-fork 1.
|
||||
Some(
|
||||
DecoyInfo::new(&tx_v_data.tx.prefix.inputs, numb_outputs, hf)
|
||||
DecoyInfo::new(&tx_v_data.tx.prefix().inputs, numb_outputs, hf)
|
||||
.map_err(ConsensusError::Transaction)?,
|
||||
)
|
||||
} else {
|
||||
|
@ -222,7 +222,7 @@ pub async fn batch_get_decoy_info<'a, D: Database + Clone + Send + 'static>(
|
|||
let unique_input_amounts = txs_verification_data
|
||||
.iter()
|
||||
.flat_map(|tx_info| {
|
||||
tx_info.tx.prefix.inputs.iter().map(|input| match input {
|
||||
tx_info.tx.prefix().inputs.iter().map(|input| match input {
|
||||
Input::ToKey { amount, .. } => amount.unwrap_or(0),
|
||||
_ => 0,
|
||||
})
|
||||
|
@ -247,7 +247,7 @@ pub async fn batch_get_decoy_info<'a, D: Database + Clone + Send + 'static>(
|
|||
|
||||
Ok(txs_verification_data.iter().map(move |tx_v_data| {
|
||||
DecoyInfo::new(
|
||||
&tx_v_data.tx.prefix.inputs,
|
||||
&tx_v_data.tx.prefix().inputs,
|
||||
|amt| outputs_with_amount.get(&amt).copied().unwrap_or(0),
|
||||
&hf,
|
||||
)
|
||||
|
|
|
@ -11,7 +11,6 @@ use futures::{FutureExt, StreamExt};
|
|||
use indexmap::IndexMap;
|
||||
use monero_serai::{
|
||||
block::{Block, BlockHeader},
|
||||
ringct::{RctBase, RctPrunable, RctSignatures},
|
||||
transaction::{Input, Timelock, Transaction, TransactionPrefix},
|
||||
};
|
||||
use proptest::{collection::vec, prelude::*};
|
||||
|
@ -98,24 +97,14 @@ prop_compose! {
|
|||
timelock in 0_usize..50_000_000,
|
||||
)
|
||||
-> Transaction {
|
||||
Transaction {
|
||||
Transaction::V1 {
|
||||
prefix: TransactionPrefix {
|
||||
version: 1,
|
||||
timelock: Timelock::Block(timelock),
|
||||
inputs: vec![Input::Gen(height)],
|
||||
outputs: vec![],
|
||||
extra,
|
||||
},
|
||||
signatures: vec![],
|
||||
rct_signatures: RctSignatures {
|
||||
base: RctBase {
|
||||
fee: 0,
|
||||
pseudo_outs: vec![],
|
||||
encrypted_amounts: vec![],
|
||||
commitments: vec![],
|
||||
},
|
||||
prunable: RctPrunable::Null
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,8 +123,8 @@ prop_compose! {
|
|||
(
|
||||
Block {
|
||||
header: BlockHeader {
|
||||
major_version: 0,
|
||||
minor_version: 0,
|
||||
hardfork_version: 0,
|
||||
hardfork_signal: 0,
|
||||
timestamp: 0,
|
||||
previous,
|
||||
nonce: 0,
|
||||
|
@ -169,7 +158,7 @@ prop_compose! {
|
|||
for (height, mut block) in blocks.into_iter().enumerate() {
|
||||
if let Some(last) = blockchain.last() {
|
||||
block.0.header.previous = *last.0;
|
||||
block.0.miner_tx.prefix.inputs = vec![Input::Gen(height as u64)]
|
||||
block.0.miner_tx.prefix_mut().inputs = vec![Input::Gen(height as u64)]
|
||||
}
|
||||
|
||||
blockchain.insert(block.0.hash(), block);
|
||||
|
|
|
@ -200,8 +200,8 @@ pub fn get_block_extended_header_from_height(
|
|||
#[allow(clippy::cast_possible_truncation)]
|
||||
Ok(ExtendedBlockHeader {
|
||||
cumulative_difficulty,
|
||||
version: block.header.major_version,
|
||||
vote: block.header.minor_version,
|
||||
version: block.header.hardfork_version,
|
||||
vote: block.header.hardfork_signal,
|
||||
timestamp: block.header.timestamp,
|
||||
block_weight: block_info.weight as usize,
|
||||
long_term_weight: block_info.long_term_weight as usize,
|
||||
|
@ -369,8 +369,8 @@ mod test {
|
|||
let b1 = block_header_from_hash;
|
||||
let b2 = block;
|
||||
assert_eq!(b1, block_header_from_height);
|
||||
assert_eq!(b1.version, b2.block.header.major_version);
|
||||
assert_eq!(b1.vote, b2.block.header.minor_version);
|
||||
assert_eq!(b1.version, b2.block.header.hardfork_version);
|
||||
assert_eq!(b1.vote, b2.block.header.hardfork_signal);
|
||||
assert_eq!(b1.timestamp, b2.block.header.timestamp);
|
||||
assert_eq!(b1.cumulative_difficulty, b2.cumulative_difficulty);
|
||||
assert_eq!(b1.block_weight, b2.weight);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, edwards::CompressedEdwardsY, Scalar};
|
||||
use monero_serai::{transaction::Timelock, H};
|
||||
use monero_serai::{generators::H, transaction::Timelock};
|
||||
|
||||
use cuprate_database::{
|
||||
RuntimeError, {DatabaseRo, DatabaseRw},
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn add_tx(
|
|||
// so the `u64/usize` is stored without any tag.
|
||||
//
|
||||
// <https://github.com/Cuprate/cuprate/pull/102#discussion_r1558504285>
|
||||
match tx.prefix.timelock {
|
||||
match tx.prefix().timelock {
|
||||
Timelock::None => (),
|
||||
Timelock::Block(height) => tables.tx_unlock_time_mut().put(&tx_id, &(height as u64))?,
|
||||
Timelock::Time(time) => tables.tx_unlock_time_mut().put(&tx_id, &time)?,
|
||||
|
@ -92,7 +92,7 @@ pub fn add_tx(
|
|||
let mut miner_tx = false;
|
||||
|
||||
// Key images.
|
||||
for inputs in &tx.prefix.inputs {
|
||||
for inputs in &tx.prefix().inputs {
|
||||
match inputs {
|
||||
// Key images.
|
||||
Input::ToKey { key_image, .. } => {
|
||||
|
@ -106,70 +106,69 @@ pub fn add_tx(
|
|||
//------------------------------------------------------ Outputs
|
||||
// Output bit flags.
|
||||
// Set to a non-zero bit value if the unlock time is non-zero.
|
||||
let output_flags = match tx.prefix.timelock {
|
||||
let output_flags = match tx.prefix().timelock {
|
||||
Timelock::None => OutputFlags::empty(),
|
||||
Timelock::Block(_) | Timelock::Time(_) => OutputFlags::NON_ZERO_UNLOCK_TIME,
|
||||
};
|
||||
|
||||
let mut amount_indices = Vec::with_capacity(tx.prefix.outputs.len());
|
||||
|
||||
for (i, output) in tx.prefix.outputs.iter().enumerate() {
|
||||
let key = *output.key.as_bytes();
|
||||
|
||||
// Outputs with clear amounts.
|
||||
let amount_index = if let Some(amount) = output.amount {
|
||||
// RingCT (v2 transaction) miner outputs.
|
||||
if miner_tx && tx.prefix.version == 2 {
|
||||
// Create commitment.
|
||||
// <https://github.com/Cuprate/cuprate/pull/102#discussion_r1559489302>
|
||||
// FIXME: implement lookup table for common values:
|
||||
// <https://github.com/monero-project/monero/blob/c8214782fb2a769c57382a999eaf099691c836e7/src/ringct/rctOps.cpp#L322>
|
||||
let commitment = (ED25519_BASEPOINT_POINT
|
||||
+ monero_serai::H() * Scalar::from(amount))
|
||||
.compress()
|
||||
.to_bytes();
|
||||
|
||||
add_rct_output(
|
||||
&RctOutput {
|
||||
key,
|
||||
height,
|
||||
output_flags,
|
||||
tx_idx: tx_id,
|
||||
commitment,
|
||||
},
|
||||
tables.rct_outputs_mut(),
|
||||
)?
|
||||
// Pre-RingCT outputs.
|
||||
} else {
|
||||
add_output(
|
||||
amount,
|
||||
let amount_indices = match &tx {
|
||||
Transaction::V1 { prefix, .. } => prefix
|
||||
.outputs
|
||||
.iter()
|
||||
.map(|output| {
|
||||
// Pre-RingCT outputs.
|
||||
Ok(add_output(
|
||||
output.amount.unwrap_or(0),
|
||||
&Output {
|
||||
key,
|
||||
key: output.key.0,
|
||||
height,
|
||||
output_flags,
|
||||
tx_idx: tx_id,
|
||||
},
|
||||
tables,
|
||||
)?
|
||||
.amount_index
|
||||
}
|
||||
// RingCT outputs.
|
||||
} else {
|
||||
let commitment = tx.rct_signatures.base.commitments[i].compress().to_bytes();
|
||||
add_rct_output(
|
||||
&RctOutput {
|
||||
key,
|
||||
height,
|
||||
output_flags,
|
||||
tx_idx: tx_id,
|
||||
commitment,
|
||||
},
|
||||
tables.rct_outputs_mut(),
|
||||
)?
|
||||
};
|
||||
.amount_index)
|
||||
})
|
||||
.collect::<Result<Vec<_>, RuntimeError>>()?,
|
||||
Transaction::V2 { prefix, proofs } => prefix
|
||||
.outputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, output)| {
|
||||
// Create commitment.
|
||||
// <https://github.com/Cuprate/cuprate/pull/102#discussion_r1559489302>
|
||||
// FIXME: implement lookup table for common values:
|
||||
// <https://github.com/monero-project/monero/blob/c8214782fb2a769c57382a999eaf099691c836e7/src/ringct/rctOps.cpp#L322>
|
||||
let commitment = if miner_tx {
|
||||
ED25519_BASEPOINT_POINT
|
||||
+ monero_serai::generators::H() * Scalar::from(output.amount.unwrap_or(0))
|
||||
} else {
|
||||
let commitment = proofs
|
||||
.as_ref()
|
||||
.expect("A V2 transaction with no RCT proofs is a miner tx")
|
||||
.base
|
||||
.commitments[i];
|
||||
|
||||
amount_indices.push(amount_index);
|
||||
} // for each output
|
||||
commitment
|
||||
};
|
||||
|
||||
(commitment, output.key.0)
|
||||
})
|
||||
.map(|(commitment, key)| {
|
||||
// Add the RCT output.
|
||||
add_rct_output(
|
||||
&RctOutput {
|
||||
key,
|
||||
height,
|
||||
output_flags,
|
||||
tx_idx: tx_id,
|
||||
commitment: commitment.compress().0,
|
||||
},
|
||||
tables.rct_outputs_mut(),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
};
|
||||
|
||||
tables
|
||||
.tx_outputs_mut()
|
||||
|
@ -227,7 +226,7 @@ pub fn remove_tx(
|
|||
//------------------------------------------------------ Key Images
|
||||
// Is this a miner transaction?
|
||||
let mut miner_tx = false;
|
||||
for inputs in &tx.prefix.inputs {
|
||||
for inputs in &tx.prefix().inputs {
|
||||
match inputs {
|
||||
// Key images.
|
||||
Input::ToKey { key_image, .. } => {
|
||||
|
@ -240,11 +239,11 @@ pub fn remove_tx(
|
|||
|
||||
//------------------------------------------------------ Outputs
|
||||
// Remove each output in the transaction.
|
||||
for output in &tx.prefix.outputs {
|
||||
for output in &tx.prefix().outputs {
|
||||
// Outputs with clear amounts.
|
||||
if let Some(amount) = output.amount {
|
||||
// RingCT miner outputs.
|
||||
if miner_tx && tx.prefix.version == 2 {
|
||||
if miner_tx && tx.version() == 2 {
|
||||
let amount_index = get_rct_num_outputs(tables.rct_outputs())? - 1;
|
||||
remove_rct_output(&amount_index, tables.rct_outputs_mut())?;
|
||||
// Pre-RingCT outputs.
|
||||
|
|
|
@ -13,7 +13,9 @@ cuprate-p2p-core = { path = "../p2p/p2p-core", features = ["borsh"] }
|
|||
|
||||
hex = { workspace = true }
|
||||
hex-literal = { workspace = true }
|
||||
monero-serai = { workspace = true, features = ["std", "http-rpc"] }
|
||||
monero-serai = { workspace = true, features = ["std"] }
|
||||
monero-simple-request-rpc = { workspace = true }
|
||||
monero-rpc = { workspace = true }
|
||||
futures = { workspace = true, features = ["std"] }
|
||||
async-trait = { workspace = true }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
|
|
|
@ -103,7 +103,8 @@ fn to_tx_verification_data(tx_blob: impl AsRef<[u8]>) -> VerifiedTransactionInfo
|
|||
let tx = Transaction::read(&mut tx_blob.as_slice()).unwrap();
|
||||
VerifiedTransactionInformation {
|
||||
tx_weight: tx.weight(),
|
||||
fee: tx.rct_signatures.base.fee,
|
||||
// TODO:
|
||||
fee: 0,
|
||||
tx_hash: tx.hash(),
|
||||
tx_blob,
|
||||
tx,
|
||||
|
@ -255,7 +256,7 @@ macro_rules! transaction_verification_data_fn {
|
|||
#[doc = concat!("assert_eq!(tx.tx_blob, ", stringify!($tx_blob), ");")]
|
||||
#[doc = concat!("assert_eq!(tx.tx_weight, ", $weight, ");")]
|
||||
#[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")]
|
||||
#[doc = "assert_eq!(tx.fee, tx.tx.rct_signatures.base.fee);"]
|
||||
// #[doc = "assert_eq!(tx.fee, tx.tx.rct_signatures.base.fee);"]
|
||||
/// ```
|
||||
pub fn $fn_name() -> &'static VerifiedTransactionInformation {
|
||||
static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new();
|
||||
|
|
|
@ -5,10 +5,9 @@ use serde::Deserialize;
|
|||
use serde_json::json;
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
use monero_serai::{
|
||||
block::Block,
|
||||
rpc::{HttpRpc, Rpc},
|
||||
};
|
||||
use monero_rpc::Rpc;
|
||||
use monero_serai::block::Block;
|
||||
use monero_simple_request_rpc::SimpleRequestRpc;
|
||||
|
||||
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||
|
||||
|
@ -18,7 +17,7 @@ use crate::rpc::constants::LOCALHOST_RPC_URL;
|
|||
/// An HTTP RPC client for Monero.
|
||||
pub struct HttpRpcClient {
|
||||
address: String,
|
||||
rpc: Rpc<HttpRpc>,
|
||||
rpc: SimpleRequestRpc,
|
||||
}
|
||||
|
||||
impl HttpRpcClient {
|
||||
|
@ -38,7 +37,7 @@ impl HttpRpcClient {
|
|||
let address = address.unwrap_or_else(|| LOCALHOST_RPC_URL.to_string());
|
||||
|
||||
Self {
|
||||
rpc: HttpRpc::new(address.clone()).await.unwrap(),
|
||||
rpc: SimpleRequestRpc::new(address.clone()).await.unwrap(),
|
||||
address,
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +50,7 @@ impl HttpRpcClient {
|
|||
|
||||
/// Access to the inner RPC client for other usage.
|
||||
#[allow(dead_code)]
|
||||
const fn rpc(&self) -> &Rpc<HttpRpc> {
|
||||
const fn rpc(&self) -> &SimpleRequestRpc {
|
||||
&self.rpc
|
||||
}
|
||||
|
||||
|
@ -123,7 +122,7 @@ impl HttpRpcClient {
|
|||
let total_tx_fees = txs.iter().map(|tx| tx.fee).sum::<u64>();
|
||||
let generated_coins = block
|
||||
.miner_tx
|
||||
.prefix
|
||||
.prefix()
|
||||
.outputs
|
||||
.iter()
|
||||
.map(|output| output.amount.expect("miner_tx amount was None"))
|
||||
|
@ -171,7 +170,8 @@ impl HttpRpcClient {
|
|||
tx_blob: tx.serialize(),
|
||||
tx_weight: tx.weight(),
|
||||
tx_hash,
|
||||
fee: tx.rct_signatures.base.fee,
|
||||
// TODO: fix this.
|
||||
fee: 0,
|
||||
tx,
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue