diff --git a/crates/subspace-farmer/src/bench_rpc_client.rs b/crates/subspace-farmer/src/bench_rpc_client.rs index 7473a32222..05a06aa0dc 100644 --- a/crates/subspace-farmer/src/bench_rpc_client.rs +++ b/crates/subspace-farmer/src/bench_rpc_client.rs @@ -139,7 +139,7 @@ impl RpcClient for BenchRpcClient { Ok(()) } - async fn records_root(&self, _: u64) -> Result, Error> { - Ok(Some(Default::default())) + async fn records_roots(&self, _: Vec) -> Result>, Error> { + Ok(Default::default()) } } diff --git a/crates/subspace-farmer/src/mock_rpc_client.rs b/crates/subspace-farmer/src/mock_rpc_client.rs index 17c57de52c..3fb67b3cfe 100644 --- a/crates/subspace-farmer/src/mock_rpc_client.rs +++ b/crates/subspace-farmer/src/mock_rpc_client.rs @@ -234,7 +234,7 @@ impl RpcClient for MockRpcClient { Ok(()) } - async fn records_root(&self, _: u64) -> Result, MockError> { - Ok(None) + async fn records_roots(&self, _: Vec) -> Result>, MockError> { + Ok(Default::default()) } } diff --git a/crates/subspace-farmer/src/node_rpc_client.rs b/crates/subspace-farmer/src/node_rpc_client.rs index 33b35c479f..c18c15c303 100644 --- a/crates/subspace-farmer/src/node_rpc_client.rs +++ b/crates/subspace-farmer/src/node_rpc_client.rs @@ -124,10 +124,13 @@ impl RpcClient for NodeRpcClient { .await?) } - async fn records_root(&self, segment_index: u64) -> Result, RpcError> { + async fn records_roots( + &self, + segment_indexes: Vec, + ) -> Result>, RpcError> { Ok(self .client - .request("subspace_recordsRoot", rpc_params![&segment_index]) + .request("subspace_recordsRoots", rpc_params![&segment_indexes]) .await?) } } diff --git a/crates/subspace-farmer/src/rpc_client.rs b/crates/subspace-farmer/src/rpc_client.rs index 1353fc9fe0..f8828d7a56 100644 --- a/crates/subspace-farmer/src/rpc_client.rs +++ b/crates/subspace-farmer/src/rpc_client.rs @@ -46,6 +46,9 @@ pub trait RpcClient: Clone + Send + Sync + 'static { /// Acknowledge receiving of archived segments async fn acknowledge_archived_segment(&self, segment_index: u64) -> Result<(), Error>; - /// Get records root for the segment - async fn records_root(&self, segment_index: u64) -> Result, Error>; + /// Get records roots for the segments + async fn records_roots( + &self, + segment_indexes: Vec, + ) -> Result>, Error>; } diff --git a/crates/subspace-farmer/src/single_plot_farm.rs b/crates/subspace-farmer/src/single_plot_farm.rs index 6274cf890c..57b83e79ff 100644 --- a/crates/subspace-farmer/src/single_plot_farm.rs +++ b/crates/subspace-farmer/src/single_plot_farm.rs @@ -25,7 +25,7 @@ use std::sync::Arc; use std::{fs, io, mem}; use subspace_archiving::archiver::is_piece_valid; use subspace_core_primitives::{ - FlatPieces, Piece, PieceIndex, PieceIndexHash, PublicKey, PIECE_SIZE, + FlatPieces, Piece, PieceIndex, PieceIndexHash, PublicKey, Sha256Hash, PIECE_SIZE, }; use subspace_networking::libp2p::identity::sr25519; use subspace_networking::libp2p::Multiaddr; @@ -733,16 +733,35 @@ impl VerifyingPlotter { return Err(PiecesVerificationError::InvalidFarmerProtocolInfo); } - for (piece, piece_index) in pieces.as_pieces().zip(piece_indexes) { - let segment_index: u64 = piece_index / records_per_segment as u64; - let position: u64 = piece_index % records_per_segment as u64; + let segment_indexes = piece_indexes + .iter() + .map(|piece_index| piece_index / records_per_segment as u64) + .collect::>(); + + let roots = self + .verification_client + .records_roots(segment_indexes) + .await + .map_err(|err| PiecesVerificationError::RpcError(err))?; + + let verified_roots = roots + .into_iter() + .zip(piece_indexes.iter()) + .map(|(root, piece_index)| { + if let Some(root) = root { + Ok(root) + } else { + error!(?piece_index, "No records root found for piece_index."); - let root = self - .verification_client - .records_root(segment_index) - .await - .map_err(|err| PiecesVerificationError::RpcError(err))? - .ok_or(PiecesVerificationError::NoRecordsRootFound)?; + Err(PiecesVerificationError::NoRecordsRootFound) + } + }) + .collect::, PiecesVerificationError>>()?; + + for ((piece, piece_index), root) in + pieces.as_pieces().zip(piece_indexes).zip(verified_roots) + { + let position: u64 = piece_index % records_per_segment as u64; if !is_piece_valid( piece, @@ -750,6 +769,8 @@ impl VerifyingPlotter { position as usize, self.farmer_protocol_info.record_size as usize, ) { + error!(?piece_index, "Piece validation failed."); + return Err(PiecesVerificationError::InvalidPieces); } }