1use bytes::Bytes;
22use crate::protocol::payload::payload::{ErrorResponseV1, PayloadRequestKind, PayloadResponseKind};
23use crate::protocol::peer::Peer;
24use crate::protocol::rpc::rpc_request::{RpcRequestPacketTx, RpcRequestPacketTxFlags};
25use crate::protocol::rpc::rpc_response::RpcResponsePacketRx;
26use crate::tools::runtime_services::RuntimeServices;
27use crate::tools::types::{Id, PQCommitmentBytes, Pow, VerificationKeyBytes};
28use crate::tools::{config, json};
29
30pub async fn rpc_server_unknown(
31 runtime_services: &RuntimeServices,
32 sponsor_id: &Id,
33 destination_address: &str,
34 payload_request_kind: PayloadRequestKind,
35 payload: Bytes,
36) -> anyhow::Result<RpcResponsePacketRx> {
37 let destination_id = Id::zero();
38 let destination_verification_key = VerificationKeyBytes::zero();
39 let destination_pq_commitment_bytes = PQCommitmentBytes::zero();
40 let flags = RpcRequestPacketTxFlags::COMPRESSED;
41 rpc_server_xxx(
42 runtime_services,
43 config::POW_MINIMUM_PER_RPC_SERVER_UNKNOWN,
44 flags,
45 sponsor_id,
46 destination_address,
47 &destination_id,
48 &destination_verification_key,
49 &destination_pq_commitment_bytes,
50 payload_request_kind,
51 payload,
52 )
53 .await
54}
55
56pub async fn rpc_server_known(
57 runtime_services: &RuntimeServices,
58 sponsor_id: &Id,
59 destination_peer: &Peer,
60 payload_request_kind: PayloadRequestKind,
61 payload: Bytes,
62) -> anyhow::Result<RpcResponsePacketRx> {
63 let flags = RpcRequestPacketTxFlags::COMPRESSED | RpcRequestPacketTxFlags::SERVER_KNOWN;
64 rpc_server_xxx(
65 runtime_services,
66 config::POW_MINIMUM_PER_RPC_SERVER_KNOWN,
67 flags,
68 sponsor_id,
69 &destination_peer.address,
70 &destination_peer.id,
71 &destination_peer.verification_key_bytes,
72 &destination_peer.pq_commitment_bytes,
73 payload_request_kind,
74 payload,
75 )
76 .await
77}
78
79pub async fn rpc_server_known_with_no_compression(
80 runtime_services: &RuntimeServices,
81 sponsor_id: &Id,
82 destination_peer: &Peer,
83 payload_request_kind: PayloadRequestKind,
84 payload: Bytes,
85) -> anyhow::Result<RpcResponsePacketRx> {
86 let flags = RpcRequestPacketTxFlags::SERVER_KNOWN;
87 rpc_server_xxx(
88 runtime_services,
89 config::POW_MINIMUM_PER_RPC_SERVER_KNOWN,
90 flags,
91 sponsor_id,
92 &destination_peer.address,
93 &destination_peer.id,
94 &destination_peer.verification_key_bytes,
95 &destination_peer.pq_commitment_bytes,
96 payload_request_kind,
97 payload,
98 )
99 .await
100}
101
102pub async fn rpc_server_known_with_requisite_pow(
103 runtime_services: &RuntimeServices,
104 sponsor_id: &Id,
105 destination_peer: &Peer,
106 payload_request_kind: PayloadRequestKind,
107 payload: Bytes,
108 requisite_pow: Pow,
109) -> anyhow::Result<RpcResponsePacketRx> {
110 let flags = RpcRequestPacketTxFlags::COMPRESSED | RpcRequestPacketTxFlags::SERVER_KNOWN;
111 rpc_server_xxx(
112 runtime_services,
113 requisite_pow,
114 flags,
115 sponsor_id,
116 &destination_peer.address,
117 &destination_peer.id,
118 &destination_peer.verification_key_bytes,
119 &destination_peer.pq_commitment_bytes,
120 payload_request_kind,
121 payload,
122 )
123 .await
124}
125
126pub async fn rpc_server_known_with_requisite_pow_and_no_compression(
127 runtime_services: &RuntimeServices,
128 sponsor_id: &Id,
129 destination_peer: &Peer,
130 payload_request_kind: PayloadRequestKind,
131 payload: Bytes,
132 requisite_pow: Pow,
133) -> anyhow::Result<RpcResponsePacketRx> {
134 let flags = RpcRequestPacketTxFlags::SERVER_KNOWN;
135 rpc_server_xxx(
136 runtime_services,
137 requisite_pow,
138 flags,
139 sponsor_id,
140 &destination_peer.address,
141 &destination_peer.id,
142 &destination_peer.verification_key_bytes,
143 &destination_peer.pq_commitment_bytes,
144 payload_request_kind,
145 payload,
146 )
147 .await
148}
149
150#[allow(clippy::too_many_arguments)] async fn rpc_server_xxx(
152 runtime_services: &RuntimeServices,
153 pow_minimum_per_rpc: Pow,
154 flags: RpcRequestPacketTxFlags,
155 sponsor_id: &Id,
156 destination_address: &str,
157 destination_id: &Id,
158 destination_verification_key_bytes: &VerificationKeyBytes,
159 destination_pq_commitment_bytes: &PQCommitmentBytes,
160 payload_request_kind: PayloadRequestKind,
161 payload: Bytes,
162) -> anyhow::Result<RpcResponsePacketRx> {
163 let rpc_request_packet = RpcRequestPacketTx::encode(runtime_services.time_provider.as_ref(), pow_minimum_per_rpc, flags, payload_request_kind, sponsor_id, destination_verification_key_bytes, destination_pq_commitment_bytes, payload, runtime_services.pow_generator.as_ref()).await?;
164
165 let response_bytes = runtime_services.transport_factory.rpc(destination_address, rpc_request_packet.bytes).await?;
166
167 let rpc_response_packet = RpcResponsePacketRx::decode(destination_id, &rpc_request_packet.pow_content_hash, config::SERVER_KEY_POW_MIN, response_bytes)?;
168
169 if rpc_response_packet.response_request_kind == PayloadResponseKind::ErrorResponseV1 {
171 let response = json::bytes_to_struct::<ErrorResponseV1>(&rpc_response_packet.bytes)?;
172 return Err(anyhow::anyhow!("server error {}: {}", response.code, response.message));
173 }
174
175 Ok(rpc_response_packet)
176}
177
178#[cfg(test)]
179mod tests {
180 use std::sync::Arc;
181 use bytes::Bytes;
182 use crate::protocol::payload::payload::{PayloadRequestKind, PayloadResponseKind};
183 use crate::protocol::rpc::rpc_request::{RpcRequestPacketRx, RpcRequestPacketTx, RpcRequestPacketTxFlags};
184 use crate::protocol::rpc::rpc_response::{RpcResponsePacketRx, RpcResponsePacketTx, RpcResponsePacketTxFlags};
185 use crate::tools::pow_generator::single_threaded_pow_generator::SingleThreadedPowGenerator;
186 use crate::tools::server_id::ServerId;
187 use crate::tools::time_provider::time_provider::RealTimeProvider;
188 use crate::tools::tools;
189 use crate::tools::{types::{Id, PQCommitmentBytes, Pow, VerificationKeyBytes}, BytesGatherer};
190 use log::trace;
191 use crate::tools::runtime_services::RuntimeServices;
192
193 #[tokio::test]
194 async fn rpc_request_packet_txrx() -> anyhow::Result<()> {
195 let runtime_services = RuntimeServices::default_for_testing();
196
197 let pow_min = Pow(12);
198 let pow_minimum_per_rpc = Pow(12);
199
200 let server_id = ServerId::new("own_pow", runtime_services.time_provider.as_ref(), pow_min, true, runtime_services.pow_generator.as_ref()).await?;
201 trace!("server_id.pow={}", server_id.pow);
202 let payload_request_kind = PayloadRequestKind::PingV1;
203 let mut payload_request = [0u8; 1024];
204 tools::random_fill_bytes(&mut payload_request);
205 let request_flags = RpcRequestPacketTxFlags::COMPRESSED | RpcRequestPacketTxFlags::SERVER_KNOWN;
206
207 let rpc_request_packet_tx = RpcRequestPacketTx::encode(
208 runtime_services.time_provider.as_ref(),
209 pow_minimum_per_rpc,
210 request_flags,
211 payload_request_kind.clone(),
212 &server_id.id,
213 &server_id.keys.verification_key_bytes,
214 &server_id.keys.pq_commitment_bytes,
215 Bytes::copy_from_slice(&payload_request),
216 runtime_services.pow_generator.as_ref(),
217 )
218 .await?;
219
220 let rpc_request_packet_rx = RpcRequestPacketRx::decode(&server_id.timestamp, &server_id.keys.verification_key_bytes, &server_id.keys.pq_commitment_bytes, rpc_request_packet_tx.bytes)?;
221 assert_eq!(payload_request_kind, rpc_request_packet_rx.payload_request_kind);
222 assert_eq!(payload_request, rpc_request_packet_rx.bytes.as_ref());
223 assert!(rpc_request_packet_rx.pow_server_known);
224
225 let mut payload_response = [0u8; 1024];
226 tools::random_fill_bytes(&mut payload_response);
227 let response_flags = RpcResponsePacketTxFlags::COMPRESSED;
228
229 let gatherer = RpcResponsePacketTx::encode(
230 &server_id.keys.signature_key,
231 &server_id.keys.verification_key_bytes,
232 &server_id.keys.pq_commitment_bytes,
233 &server_id.sponsor_id,
234 &server_id.timestamp,
235 &server_id.hash,
236 &server_id.salt,
237 &rpc_request_packet_rx.pow_content_hash,
238 response_flags,
239 PayloadResponseKind::PingResponseV1,
240 BytesGatherer::from_bytes(Bytes::copy_from_slice(&payload_response)),
241 )?;
242
243 let rpc_response_packet_rx = RpcResponsePacketRx::decode(&server_id.id, &rpc_request_packet_rx.pow_content_hash, pow_min, gatherer.to_bytes())?;
244
245 assert_eq!(rpc_response_packet_rx.response_request_kind, PayloadResponseKind::PingResponseV1);
246 assert_eq!(rpc_response_packet_rx.bytes.as_ref(), payload_response);
247
248 Ok(())
249 }
250
251 #[tokio::test]
252 async fn rpc_request_packet_txrx_server_unknown() -> anyhow::Result<()> {
253 let time_provider = RealTimeProvider;
254 let pow_generator: Arc<dyn crate::tools::pow_generator::pow_generator::PowGenerator> = Arc::new(SingleThreadedPowGenerator::new());
255
256 let pow_min_for_server_id = Pow(12);
257 let pow_min_for_rpc = Pow(12);
258
259 let server_id = ServerId::new("own_pow", &time_provider, pow_min_for_server_id, true, pow_generator.as_ref()).await?;
260 let payload_request_kind = PayloadRequestKind::PingV1;
261 let mut payload_request = [0u8; 1024];
262 tools::random_fill_bytes(&mut payload_request);
263 let flags = RpcRequestPacketTxFlags::COMPRESSED;
264
265 let rpc_request_packet_tx = RpcRequestPacketTx::encode(&time_provider, pow_min_for_rpc, flags, payload_request_kind.clone(), &Id::zero(), &VerificationKeyBytes::zero(), &PQCommitmentBytes::zero(), Bytes::copy_from_slice(&payload_request), pow_generator.as_ref()).await?;
266
267 let rpc_request_packet_rx = RpcRequestPacketRx::decode(&server_id.timestamp, &server_id.keys.verification_key_bytes, &server_id.keys.pq_commitment_bytes, rpc_request_packet_tx.bytes)?;
268 assert_eq!(payload_request_kind, rpc_request_packet_rx.payload_request_kind);
269 assert_eq!(payload_request, rpc_request_packet_rx.bytes.as_ref());
270 assert!(!rpc_request_packet_rx.pow_server_known);
271
272 let mut payload_response = [0u8; 1024];
273 tools::random_fill_bytes(&mut payload_response);
274 let response_flags = RpcResponsePacketTxFlags::COMPRESSED;
275 let gatherer = RpcResponsePacketTx::encode(
276 &server_id.keys.signature_key,
277 &server_id.keys.verification_key_bytes,
278 &server_id.keys.pq_commitment_bytes,
279 &server_id.sponsor_id,
280 &server_id.timestamp,
281 &server_id.hash,
282 &server_id.salt,
283 &rpc_request_packet_rx.pow_content_hash,
284 response_flags,
285 PayloadResponseKind::PingResponseV1,
286 BytesGatherer::from_bytes(Bytes::copy_from_slice(&payload_response)),
287 )?;
288
289 let rpc_response_packet_rx = RpcResponsePacketRx::decode(&Id::zero(), &rpc_request_packet_rx.pow_content_hash, pow_min_for_server_id, gatherer.to_bytes())?;
290
291 assert_eq!(rpc_response_packet_rx.response_request_kind, PayloadResponseKind::PingResponseV1);
292 assert_eq!(rpc_response_packet_rx.bytes.as_ref(), payload_response);
293
294 Ok(())
295 }
296
297 use crate::protocol::rpc::rpc_response::RPC_RESPONSE_PACKET_VERSION;
300 use crate::tools::types::{Hash, Signature, Salt, HASH_BYTES, ID_BYTES, PQ_COMMITMENT_BYTES, SALT_BYTES, SIGNATURE_BYTES, VERIFICATION_KEY_BYTES};
301 use crate::tools::time::TIME_MILLIS_BYTES;
302
303 const RESPONSE_SIGNATURE_OFFSET: usize = 1 + 1 + 2 + VERIFICATION_KEY_BYTES + PQ_COMMITMENT_BYTES + ID_BYTES + TIME_MILLIS_BYTES + HASH_BYTES + SALT_BYTES;
304 const RESPONSE_SALT_OFFSET: usize = RESPONSE_SIGNATURE_OFFSET + SIGNATURE_BYTES;
305
306 fn encode_test_response(server_id: &ServerId, pow_content_hash: &Hash) -> anyhow::Result<Bytes> {
307 let bytes_gatherer = RpcResponsePacketTx::encode(
308 &server_id.keys.signature_key,
309 &server_id.keys.verification_key_bytes,
310 &server_id.keys.pq_commitment_bytes,
311 &server_id.sponsor_id,
312 &server_id.timestamp,
313 &server_id.hash,
314 &server_id.salt,
315 pow_content_hash,
316 RpcResponsePacketTxFlags::COMPRESSED,
317 PayloadResponseKind::ErrorResponseV1,
318 BytesGatherer::from_bytes(Bytes::from_static(b"{}")),
319 )?;
320 Ok(bytes_gatherer.to_bytes())
321 }
322
323 fn extract_response_signature(response_bytes: &Bytes) -> anyhow::Result<Signature> {
324 Ok(Signature(response_bytes[RESPONSE_SIGNATURE_OFFSET..RESPONSE_SIGNATURE_OFFSET + SIGNATURE_BYTES].try_into()?))
325 }
326
327 fn extract_response_salt(response_bytes: &Bytes) -> anyhow::Result<Salt> {
328 Ok(Salt(response_bytes[RESPONSE_SALT_OFFSET..RESPONSE_SALT_OFFSET + SALT_BYTES].try_into()?))
329 }
330
331 async fn test_server_id(runtime_services: &RuntimeServices) -> anyhow::Result<ServerId> {
332 ServerId::new("own_pow", runtime_services.time_provider.as_ref(), Pow(8), true, runtime_services.pow_generator.as_ref()).await
333 }
334
335 #[tokio::test]
336 async fn rpc_response_signature_is_not_a_signing_oracle_for_peer() -> anyhow::Result<()> {
337 let runtime_services = RuntimeServices::default_for_testing();
338 let server_id = test_server_id(&runtime_services).await?;
339
340 let mut forged_peer = server_id.to_peer(runtime_services.time_provider.as_ref())?;
343 forged_peer.address = "6.6.6.6:666".to_string();
344 forged_peer.timestamp = TimeMillis(i64::MAX / 2);
345 let forged_peer_digest = forged_peer.signature_hash_generate()?;
346
347 {
349 let mut unsalted_forged_peer = forged_peer.clone();
350 unsalted_forged_peer.signature = crate::tools::signing::sign(&server_id.keys.signature_key, forged_peer_digest.as_ref());
351 assert!(unsalted_forged_peer.verify().is_ok(), "test setup: raw-digest signature should forge the peer");
352 }
353
354 let response_bytes = encode_test_response(&server_id, &forged_peer_digest)?;
356 forged_peer.signature = extract_response_signature(&response_bytes)?;
357 assert!(forged_peer.verify().is_err(), "response signature must not be usable as a Peer signature");
358
359 RpcResponsePacketRx::decode(&server_id.id, &forged_peer_digest, Pow(8), response_bytes)?;
361 Ok(())
362 }
363
364 #[tokio::test]
365 async fn rpc_response_signature_is_not_a_signing_oracle_for_submit_post_claim_token() -> anyhow::Result<()> {
366 use crate::protocol::payload::payload::SubmitPostClaimTokenV1;
367 use crate::tools::buckets::{BucketLocation, BucketType, BUCKET_DURATIONS};
368
369 let runtime_services = RuntimeServices::default_for_testing();
370 let server_id = test_server_id(&runtime_services).await?;
371 let peer = server_id.to_peer(runtime_services.time_provider.as_ref())?;
372 let bucket_location = BucketLocation::new(BucketType::User, Id::random(), BUCKET_DURATIONS[0], TimeMillis(1_000_000))?;
373 let post_id = Id::random();
374
375 let claim_token_digest = hashing::hash_multiple(&[peer.id.as_ref(), bucket_location.get_hash_for_signing().as_ref(), post_id.as_ref(), "SubmitPostClaimTokenV1".as_bytes()]);
377
378 let genuine_claim_token = SubmitPostClaimTokenV1::new(peer.clone(), bucket_location.clone(), post_id, &server_id.keys.signature_key);
380 assert_eq!(genuine_claim_token.token_signature, crate::tools::signing::sign(&server_id.keys.signature_key, claim_token_digest.as_ref()));
381
382 let response_bytes = encode_test_response(&server_id, &claim_token_digest)?;
383 let forged_claim_token = SubmitPostClaimTokenV1 { peer, bucket_location, post_id, token_signature: extract_response_signature(&response_bytes)? };
384 assert!(forged_claim_token.verify().is_err(), "response signature must not be usable as a claim token signature");
385 Ok(())
386 }
387
388 #[tokio::test]
389 async fn rpc_response_salt_or_signature_tamper_is_rejected() -> anyhow::Result<()> {
390 let runtime_services = RuntimeServices::default_for_testing();
391 let server_id = test_server_id(&runtime_services).await?;
392 let pow_content_hash = hashing::hash(b"some request");
393 let response_bytes = encode_test_response(&server_id, &pow_content_hash)?;
394
395 RpcResponsePacketRx::decode(&server_id.id, &pow_content_hash, Pow(8), response_bytes.clone())?;
396
397 for tamper_offset in [RESPONSE_SALT_OFFSET, RESPONSE_SALT_OFFSET + SALT_BYTES - 1, RESPONSE_SIGNATURE_OFFSET, RESPONSE_SALT_OFFSET - 1] {
398 let mut tampered_response_bytes = response_bytes.to_vec();
399 tampered_response_bytes[tamper_offset] ^= 0x01;
400 assert!(RpcResponsePacketRx::decode(&server_id.id, &pow_content_hash, Pow(8), Bytes::from(tampered_response_bytes)).is_err(), "tamper at offset {} must be rejected", tamper_offset);
401 }
402 Ok(())
403 }
404
405 #[tokio::test]
406 async fn rpc_response_old_version_is_rejected() -> anyhow::Result<()> {
407 let runtime_services = RuntimeServices::default_for_testing();
408 let server_id = test_server_id(&runtime_services).await?;
409 let pow_content_hash = hashing::hash(b"some request");
410 let response_bytes = encode_test_response(&server_id, &pow_content_hash)?;
411 assert_eq!(response_bytes[0], RPC_RESPONSE_PACKET_VERSION);
412
413 let mut old_version_response_bytes = response_bytes.to_vec();
414 old_version_response_bytes[0] = 1;
415 let error = RpcResponsePacketRx::decode(&server_id.id, &pow_content_hash, Pow(8), Bytes::from(old_version_response_bytes)).err().expect("version 1 must be rejected");
416 assert!(error.to_string().contains("Unsupported RpcResponsePacket version: 1"), "unexpected error: {}", error);
417 Ok(())
418 }
419
420 #[tokio::test]
421 async fn rpc_response_salt_is_fresh_per_response() -> anyhow::Result<()> {
422 let runtime_services = RuntimeServices::default_for_testing();
423 let server_id = test_server_id(&runtime_services).await?;
424 let pow_content_hash = hashing::hash(b"some request");
425
426 let response_bytes_1 = encode_test_response(&server_id, &pow_content_hash)?;
427 let response_bytes_2 = encode_test_response(&server_id, &pow_content_hash)?;
428 assert_ne!(extract_response_salt(&response_bytes_1)?, extract_response_salt(&response_bytes_2)?);
429 assert_ne!(extract_response_signature(&response_bytes_1)?, extract_response_signature(&response_bytes_2)?);
430
431 RpcResponsePacketRx::decode(&server_id.id, &pow_content_hash, Pow(8), response_bytes_1)?;
432 RpcResponsePacketRx::decode(&server_id.id, &pow_content_hash, Pow(8), response_bytes_2)?;
433 Ok(())
434 }
435
436 use crate::tools::time::TimeMillis;
439 use crate::tools::hashing;
440
441 #[test]
442 fn rpc_request_decode_empty_input() {
443 let timestamp = TimeMillis::zero();
444 let verification_key_bytes = VerificationKeyBytes::zero();
445 let pq_commitment_bytes = PQCommitmentBytes::zero();
446 assert!(RpcRequestPacketRx::decode(×tamp, &verification_key_bytes, &pq_commitment_bytes, Bytes::new()).is_err());
447 }
448
449 #[test]
450 fn rpc_request_decode_single_byte() {
451 let timestamp = TimeMillis::zero();
452 let verification_key_bytes = VerificationKeyBytes::zero();
453 let pq_commitment_bytes = PQCommitmentBytes::zero();
454 assert!(RpcRequestPacketRx::decode(×tamp, &verification_key_bytes, &pq_commitment_bytes, Bytes::from_static(&[1u8])).is_err());
455 }
456
457 #[test]
458 fn rpc_request_decode_garbage() {
459 let timestamp = TimeMillis::zero();
460 let verification_key_bytes = VerificationKeyBytes::zero();
461 let pq_commitment_bytes = PQCommitmentBytes::zero();
462 assert!(RpcRequestPacketRx::decode(×tamp, &verification_key_bytes, &pq_commitment_bytes, Bytes::from_static(&[0xff; 256])).is_err());
463 }
464
465 #[test]
468 fn rpc_response_decode_empty_input() {
469 let destination_id = Id::zero();
470 let pow_content_hash = hashing::hash(&[0u8]);
471 assert!(RpcResponsePacketRx::decode(&destination_id, &pow_content_hash, Pow(0), Bytes::new()).is_err());
472 }
473
474 #[test]
475 fn rpc_response_decode_single_byte() {
476 let destination_id = Id::zero();
477 let pow_content_hash = hashing::hash(&[0u8]);
478 assert!(RpcResponsePacketRx::decode(&destination_id, &pow_content_hash, Pow(0), Bytes::from_static(&[1u8])).is_err());
479 }
480
481 #[test]
482 fn rpc_response_decode_garbage() {
483 let destination_id = Id::zero();
484 let pow_content_hash = hashing::hash(&[0u8]);
485 assert!(RpcResponsePacketRx::decode(&destination_id, &pow_content_hash, Pow(0), Bytes::from_static(&[0xff; 256])).is_err());
486 }
487
488 #[test]
489 fn rpc_response_decode_header_too_short_for_payload_len() {
490 let mut data = vec![0u8; 222];
495 data[0] = crate::protocol::rpc::rpc_response::RPC_RESPONSE_PACKET_VERSION;
496 let destination_id = Id::zero();
497 let pow_content_hash = hashing::hash(&[0u8]);
498 assert!(RpcResponsePacketRx::decode(&destination_id, &pow_content_hash, Pow(0), Bytes::from(data)).is_err());
499 }
500
501 #[cfg(not(target_arch = "wasm32"))]
502 mod bolero_fuzz {
503 use bytes::Bytes;
504 use crate::protocol::rpc::rpc_request::RpcRequestPacketRx;
505 use crate::protocol::rpc::rpc_response::RpcResponsePacketRx;
506 use crate::tools::types::{Id, PQCommitmentBytes, Pow, VerificationKeyBytes};
507 use crate::tools::time::TimeMillis;
508 use crate::tools::hashing;
509
510 #[test]
511 fn fuzz_rpc_request_decode() {
512 bolero::check!().for_each(|data: &[u8]| {
513 let timestamp = TimeMillis::zero();
514 let verification_key_bytes = VerificationKeyBytes::zero();
515 let pq_commitment_bytes = PQCommitmentBytes::zero();
516 let _ = RpcRequestPacketRx::decode(×tamp, &verification_key_bytes, &pq_commitment_bytes, Bytes::copy_from_slice(data));
517 });
518 }
519
520 #[test]
521 fn fuzz_rpc_response_decode() {
522 bolero::check!().for_each(|data: &[u8]| {
523 let destination_id = Id::zero();
524 let pow_content_hash = hashing::hash(&[0u8]);
525 let _ = RpcResponsePacketRx::decode(&destination_id, &pow_content_hash, Pow(0), Bytes::copy_from_slice(data));
526 });
527 }
528 }
529}