New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pieces verification to farmers. #725
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally in line with my expectations, no major issues
@@ -95,6 +97,9 @@ pub trait SubspaceRpcApi { | |||
|
|||
#[method(name = "subspace_acknowledgeArchivedSegment")] | |||
async fn acknowledge_archived_segment(&self, segment_index: u64) -> RpcResult<()>; | |||
|
|||
#[method(name = "subspace_recordsRoot")] | |||
async fn records_root(&self, segment_index: u64) -> RpcResult<Option<Sha256Hash>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should take a vector of segment indexes and return a vector of roots to improve efficiency, otherwise there might be too many requests necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sure. However, it seems vulnerable to a large indexes vector. It makes sense to introduce MAX_SEGMENT_INDEXES_PER_REQUEST
const to limit both farmer and node sides.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly. Requester needs to limit number of roots requested or else response will not fit into max size configured in RPC server and response will fail. For public RPC endpoints we also may want to limit this, so yeah, makes sense to have certain limits on both sides.
let segment_index: u64 = piece_index / MERKLE_NUM_LEAVES as u64; | ||
let position: u64 = piece_index % MERKLE_NUM_LEAVES as u64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MERKLE_NUM_LEAVES
and RECORD_SIZE
should be derived from FarmerProtocolInfo
instead, it allows us to have different values in tests and generally make implementation on the library level more flexible. This is the first time these constants are used on the farmer specifically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Please, verify the new algorithm.
# Conflicts: # crates/sc-consensus-subspace-rpc/src/lib.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
let records_per_segment = | ||
farmer_protocol_info.recorded_history_segment_size as usize / PIECE_SIZE; | ||
if farmer_protocol_info.record_size.is_zero() || records_per_segment.is_zero() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be preferable to change record_size
and recorded_history_segment_size
to NonZeroU32
, then you don't ever need to check it. At least in FarmerProtocolInfo
🙂
It is always better to make invalid invariants non-representable in the first place. Though I don't think these two were ever zero anywhere in our codebase anyway. And segment size was always bigger than piece size.
@@ -95,6 +97,9 @@ pub trait SubspaceRpcApi { | |||
|
|||
#[method(name = "subspace_acknowledgeArchivedSegment")] | |||
async fn acknowledge_archived_segment(&self, segment_index: u64) -> RpcResult<()>; | |||
|
|||
#[method(name = "subspace_recordsRoot")] | |||
async fn records_root(&self, segment_index: u64) -> RpcResult<Option<Sha256Hash>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly. Requester needs to limit number of roots requested or else response will not fit into max size configured in RPC server and response will fail. For public RPC endpoints we also may want to limit this, so yeah, makes sense to have certain limits on both sides.
- change u32 to NonZeroU32 for record_size
- add MAX_SEGMENT_INDEXES_PER_REQUEST limit to rpc call on both client and server sides.
The latest changes comment:
|
# Conflicts: # crates/subspace-farmer/src/single_plot_farm.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something broke DSN test reliably and needs to be fixed
- refactor rpc_client module in the subspace-farmer - fix error comment in sc-consensus-subspace-rpc - fix broken test
Fixed. |
This PR aims to add pieces verification to the DSN sync on farmers. It introduces an additional RPC endpoint on the node side to get the
records_root
.Original issue: #709
Changes
records_root
endpoint forSubspaceRpcApi
in thesc-consensus-subspace-rpc
cratepieces_verification
module in thesubspace-farmer
records_root
in thesubspace-farmer
Comments
--dsn-sync
flag in themain
branch.Code contributor checklist: