-
Notifications
You must be signed in to change notification settings - Fork 55
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
PeerDAS: Add raw functions like eip4844 #282
Conversation
68e0697
to
25a176c
Compare
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.
Hello 👋,
kzg/src/das.rs
file is for abstract das implementation, with configurable trusted setup size and cell size. So for ethereum-specific parameters it is better to put code into kzg/src/eth/...
module, maybe kzg/src/eth/eip_7594
?
Probably you can do something like:
// kzg/src/eth/eip_7594.rs file
pub fn recover_cells_and_kzg_proofs_raw::<B: EcBackend>(das: &impl DAS<B>, cell_indices: &[usize], cells: &[[u8; BYTES_PER_CELL]]) -> Result<CellsKzgProofs, String> {
// ...
}
I believe, then you can use this function like so:
recover_cells_and_kzg_proofs_raw::<BlstBackend>(settings(), cell_indices, cells)
Few things to keep in mind:
- our implementation saves cells in flat slice, so you probably want to group frs / flatten your input. Because of fixed-size slices, memory layout actually stays the same, so flattening should be zero-cost
- c-kzg-4844 in
recover_cells_and_kzg_proofs
function allows to recover only cells, without proofs. Same incompute_cells_and_kzg_proofs
, you can select - compute only cells, only proofs, or both. However,rust-eth-kzg
doesn't provide such functionality. So we chose to implement as c-kzg does this, but they're not very convenient, as you need to pre-allocate output slices :). So choose what better works for you, just keep in mind that you can skip some computations.
If you need some more help, just ping me 😄
kzg/src/das.rs
Outdated
let mut recovered_cells: Vec<B::Fr> = vec![]; | ||
let mut recovered_proofs: Vec<B::G1> = vec![]; |
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.
You need to pre-allocate space for recovered_cells and recovered_proofs. You can look at the examples in test cases:
rust-kzg/kzg-bench/src/tests/eip_7594.rs
Lines 132 to 135 in cb71d62
let mut recv_cells = | |
vec![B::Fr::default(); eth::CELLS_PER_EXT_BLOB * eth::FIELD_ELEMENTS_PER_CELL]; | |
let mut recv_proofs = vec![B::G1::default(); eth::CELLS_PER_EXT_BLOB]; |
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.
Oh, this is already fixed :)
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.
ohh, yeah. I already update those with the force-commit
@ArtiomTr you are right, I'll update according to your suggestions |
25a176c
to
7075d37
Compare
Hello @ArtiomTr I've been updated to follow your suggestions to move peerdas-specific functions into its own module, outside of das-abstract trait, please kindly review the changes :) |
7075d37
to
c9615a3
Compare
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.
Looks good, just minor nitpicks 👍
kzg/src/eth/eip_7594.rs
Outdated
let _ = das.recover_cells_and_kzg_proofs( | ||
&mut recovered_cells, | ||
Some(&mut recovered_proofs), | ||
cell_indices, | ||
&cells, | ||
); |
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 believe there should be ?
, because you're currently ignoring error, if it occurs in recover_cells_and_kzg_proofs:
let _ = das.recover_cells_and_kzg_proofs( | |
&mut recovered_cells, | |
Some(&mut recovered_proofs), | |
cell_indices, | |
&cells, | |
); | |
das.recover_cells_and_kzg_proofs( | |
&mut recovered_cells, | |
Some(&mut recovered_proofs), | |
cell_indices, | |
&cells, | |
)?; |
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.
ahh! good eyes
kzg/src/eth/eip_7594.rs
Outdated
let _ = das.compute_cells_and_kzg_proofs( | ||
Some(&mut recovered_cells), | ||
Some(&mut recovered_proofs), | ||
&blob, | ||
); |
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.
Same issue as above, with recover_cells_and_kzg_proofs
kzg/src/eth/eip_7594.rs
Outdated
let nested_cells = cfg_iter!(cells) | ||
.map(|bytes| bytes_to_cell::<B>(bytes)) | ||
.collect::<Result<Vec<Vec<_>>, _>>()?; | ||
let cells = nested_cells.into_iter().flatten().collect::<Vec<_>>(); |
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'm not sure, but looks like it would be better to do flatten
first, and then conversion - that way you can avoid heap allocation (collecting each cell to vector), and also flattening will be zero-cost, as memory layout is not changed:
let nested_cells = cfg_iter!(cells) | |
.map(|bytes| bytes_to_cell::<B>(bytes)) | |
.collect::<Result<Vec<Vec<_>>, _>>()?; | |
let cells = nested_cells.into_iter().flatten().collect::<Vec<_>>(); | |
let cells = cfg_iter!(cells.flatten()).map(B::Fr::from_bytes).collect::<Result<Vec<_>, String>>()?; |
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.
flatten is not available in the slice array, which should be the better way?
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.
Oh sorry, I mean as_flattened
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.
but, even if we do so, the bytes size will not fit into the field element, we need to chunk it first anyway
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.
Yeah, you're right, too rushed with this suggestion. It should be:
let nested_cells = cfg_iter!(cells) | |
.map(|bytes| bytes_to_cell::<B>(bytes)) | |
.collect::<Result<Vec<Vec<_>>, _>>()?; | |
let cells = nested_cells.into_iter().flatten().collect::<Vec<_>>(); | |
let cells = cfg_iter!(cells.as_flattened().chunks(BYTES_PER_FIELD_ELEMENT)).map(B::Fr::from_bytes).collect::<Result<Vec<_>, _>>()?; |
The point was that we can avoid unnecessary heap allocations, and keep only one
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 could not use cfg_iter
on chunks, so remove on cells
for now, will improve it later
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.
Ah right, chunks is already an iterator. There is par_chunks
in rayon, but I believe it wouldn't give much performance improvement
kzg/src/eth/eip_7594.rs
Outdated
let nested_cells = cfg_iter!(cells) | ||
.map(|bytes| bytes_to_cell::<B>(bytes)) | ||
.collect::<Result<Vec<Vec<_>>, _>>()?; | ||
let cells = nested_cells.into_iter().flatten().collect::<Vec<_>>(); |
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.
Same as in recover_cells_and_kzg_proofs_raw
, heap allocations and flattening could be simplified
kzg/src/eth/eip_7594.rs
Outdated
let chunk_size = FIELD_ELEMENTS_PER_CELL; | ||
if bytes.len() % chunk_size != 0 { | ||
return Err(format!("Invalid byte length. got {}", bytes.len(),)); | ||
} |
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 you can just check here, if slice size is equal to FIELD_ELEMENTS_PER_EXT_BLOB
kzg/src/eth/eip_7594.rs
Outdated
if end > BYTES_PER_CELL { | ||
return Err(format!( | ||
"Invalid cell byte length. Expected {} got {}", | ||
BYTES_PER_CELL, end, | ||
)); | ||
} |
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.
Looks like this check is unnecessary, as chunks
function already returns slices, with size <= chunk_size.
c9615a3
to
8180599
Compare
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.
Perfect 👌
* fix clippy * add comments after debug * add placeholder byte into `recovered_cells` and `recovered_proofs` * move peerdas-specific functions outside of das-abstract trait * avoid multiple heap allocation * add cfg_chunks macro
8180599
to
24df982
Compare
Hello, just added |
@ArtiomTr Can we merge this PR so I can switch to use |
I approve, but I don't have merge rights to this repo 😄 I believe @sauliusgrigaitis can help |
Okay, I'll ask him for help |
Thanks @sauliusgrigaitis 🙏 |
This pull request will add raw functions into DAS trait, like eip4844 in this commit. The idea is to allow easier integration into its domain without needing to transform unit type into underlying field element type (e.g. converting
Cell
into field elements), which adding more complexity into the integration. The WIP integration intograndine
can be found here.NOTE: the current changes has a few bugs (potential issues have been marked as well), which give the following error when test in the integration:
the error is pointing to kzg/src/das.rs, which I'm not quite familiar with the logic here.
UPDATED: the bug has been fixed, after creating the issue :)
cc @ArtiomTr, please help review the changes and give some suggestions