-
Notifications
You must be signed in to change notification settings - Fork 270
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
implement SyscallGetSysvar #1307
Conversation
5a41911
to
aab4e6e
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1307 +/- ##
========================================
Coverage 81.5% 81.6%
========================================
Files 867 867
Lines 368866 369395 +529
========================================
+ Hits 300978 301442 +464
- Misses 67888 67953 +65 |
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.
This looks good to me, just one suggestion on the compute calculation.
I also feel like we should isolate the two syscall getter tests. Not only would this make it much clearer which syscall might be failing in a test, etc.s, but it also makes it much easier to deprecate the old syscalls and cut those tests out.
.saturating_add(32_u64.div_ceil(cpi_bytes_per_unit)) | ||
.saturating_add(std::cmp::max( | ||
length.div_ceil(cpi_bytes_per_unit), | ||
mem_op_base_cost, | ||
)), |
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.
These divisions should be floor. The SIMD just uses /
(🙃) but FD previously mentioned floor was preferred.
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.
updated! as for the tests, i prefered to keep them together to test that both syscall results match the same "clean" object (and thus match each other). maybe i should keep them together but use separate memory mappings tho?
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.
That's a good point. Maybe the tests are ok as-is. I don't feel strongly about it, so up to you!
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 great, nice work!
// clone is to zero the alignment padding | ||
let epochschedule_from_buf = | ||
bincode::deserialize::<EpochSchedule>(&got_epochschedule_buf) | ||
.unwrap() | ||
.clone(); | ||
|
||
assert_eq!(epochschedule_from_buf, src_epochschedule); | ||
assert!(are_bytes_equal( | ||
&epochschedule_from_buf, | ||
&clean_epochschedule | ||
)); |
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.
Just checking: This first assertion would pass without the clone, right? It's only to have the bytes equal? Just trying to think how we need to handle padding in the API that we expose to programs.
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 thats right, the objects are equal by the rules of rust, and the clone is just for comparing the memory mapping using unsafe
. ill move the clone down so thats explicit
everything presently exposed to programs goes through get_sysvar
, so theres no change:
let var = translate_type_mut::<T>(memory_mapping, var_addr, check_aligned)?;
// this clone looks unecessary now, but it exists to zero out trailing alignment bytes
// it is unclear whether this should ever matter
// but there are tests using MemoryMapping that expect to see this
// we preserve the previous behavior out of an abundance of caution
let sysvar: Arc<T> = sysvar?;
*var = T::clone(sysvar.as_ref());
Ok(SUCCESS)
when we transition to the new syscall we just need to preserve that behavior (or decide we dont need to carry it over. its very likely not to matter)
Problem
we have proposed a syscall,
sol_get_sysvar
/SyscallGetSysvar
, a generic mechanism to fetch arbitrary slices of account data for a specially selected list of sysvars. this is intended primarily to enable the bpf versions of the stake and vote programs to access individual parts of the stake history and slot hashes sysvars, but it also functions as a drop-in replacement for all existing non-deprecated sysvar syscallssee discussion in SIMD-0127 for (much) more context
Summary of Changes
necessary
SysvarCache
changes for this pr are in #560this pr introduces a new feature-gated syscall,
SyscallGetSysvar
, which accepts a sysvar id, length, offset, and destination buffer, and:length
tolength+offset
into the destinationnothing presently uses this syscall. forthcoming prs intended for the same agave version will use it to implement fetching parts of stake history and slot hashes, though nothing will use them until the feature is active on all networks. also, in a future version, all existing sysvar syscalls can be deprecated, and the existing
Sysvar::get
macro can use this syscall insteadthis pr has been made as simple as possible, in line with the simd that defines it, hence deferring the usage of the syscall into its own, third, pr (which should not require a featuregate itself)
Feature Gate Issue: #615