-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Change read
behavior on the InMemoryTransaction
to use offset and allow not equal buf size
#2673
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -398,14 +398,22 @@ where | |
if let Some(operation) = self.get_from_changes(key, column) { | ||
match operation { | ||
WriteOperation::Insert(value) => { | ||
let read = value.len(); | ||
if read != buf.len() { | ||
return Err(crate::Error::Other(anyhow::anyhow!( | ||
"Buffer size is not equal to the value size" | ||
))); | ||
let bytes_len = value.as_ref().len(); | ||
let start = offset; | ||
let buf_len = buf.len(); | ||
let end = offset.saturating_add(buf.len()); | ||
|
||
if end > bytes_len { | ||
return Err(anyhow::anyhow!( | ||
"Offset `{offset}` + buf_len `{buf_len}` read until {end} which is out of bounds `{bytes_len}` for key `{:?}`", | ||
key | ||
) | ||
.into()); | ||
} | ||
buf.copy_from_slice(value.as_ref()); | ||
Ok(Some(read)) | ||
|
||
let starting_from_offset = &value.as_ref()[start..end]; | ||
buf[..].copy_from_slice(starting_from_offset); | ||
Ok(Some(buf_len)) | ||
} | ||
WriteOperation::Remove => Ok(None), | ||
} | ||
|
@@ -656,6 +664,68 @@ mod test { | |
use super::*; | ||
use crate::column::Column; | ||
|
||
#[test] | ||
fn read_returns_from_view_exact_size() { | ||
// setup | ||
let storage = InMemoryStorage::<Column>::default(); | ||
let mut view = storage.read_transaction(); | ||
let key = vec![0xA, 0xB, 0xC]; | ||
let expected = Value::from([1, 2, 3]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we probably shouldn't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we address in a follow up? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
view.put(&key, Column::Metadata, expected.clone()).unwrap(); | ||
// test | ||
let mut buf = [0; 3]; | ||
let ret = view.read(&key, Column::Metadata, 0, &mut buf).unwrap(); | ||
// verify | ||
assert_eq!(ret, Some(3)); | ||
assert_eq!(buf, [1, 2, 3]); | ||
} | ||
|
||
#[test] | ||
fn read_returns_from_view_buf_smaller() { | ||
// setup | ||
let storage = InMemoryStorage::<Column>::default(); | ||
let mut view = storage.read_transaction(); | ||
let key = vec![0xA, 0xB, 0xC]; | ||
let expected = Value::from([1, 2, 3]); | ||
view.put(&key, Column::Metadata, expected.clone()).unwrap(); | ||
// test | ||
let mut buf = [0; 2]; | ||
let ret = view.read(&key, Column::Metadata, 0, &mut buf).unwrap(); | ||
// verify | ||
assert_eq!(ret, Some(2)); | ||
assert_eq!(buf, [1, 2]); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add another test with offset and passing. Could just be the same as this but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
#[test] | ||
fn read_returns_from_view_buf_bigger() { | ||
// setup | ||
let storage = InMemoryStorage::<Column>::default(); | ||
let mut view = storage.read_transaction(); | ||
let key = vec![0xA, 0xB, 0xC]; | ||
let expected = Value::from([1, 2, 3]); | ||
view.put(&key, Column::Metadata, expected.clone()).unwrap(); | ||
// test | ||
let mut buf = [0; 4]; | ||
let ret = view.read(&key, Column::Metadata, 0, &mut buf).unwrap_err(); | ||
// verify | ||
assert_eq!(ret, crate::Error::Other(anyhow::anyhow!("Offset `0` + buf_len `4` read until 4 which is out of bounds `3` for key `[10, 11, 12]`".to_string()))); | ||
} | ||
|
||
#[test] | ||
fn read_returns_from_view_buf_bigger_because_offset() { | ||
// setup | ||
let storage = InMemoryStorage::<Column>::default(); | ||
let mut view = storage.read_transaction(); | ||
let key = vec![0xA, 0xB, 0xC]; | ||
let expected = Value::from([1, 2, 3]); | ||
view.put(&key, Column::Metadata, expected.clone()).unwrap(); | ||
// test | ||
let mut buf = [0; 3]; | ||
let ret = view.read(&key, Column::Metadata, 1, &mut buf).unwrap_err(); | ||
// verify | ||
assert_eq!(ret, crate::Error::Other(anyhow::anyhow!("Offset `1` + buf_len `3` read until 4 which is out of bounds `3` for key `[10, 11, 12]`".to_string()))); | ||
} | ||
|
||
#[test] | ||
fn get_returns_from_view() { | ||
// setup | ||
|
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.
technically the bug was introduced in #2438, the change in fuel-vm seems to be working as expected from what I can tell
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.
For me it's FuelLabs/fuel-vm#847 that broke CCP and LDC opcode if this PR hasn't land on master, the
read
function would have been wrong since #2438 but the opcode would have been fine.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.
yep, but the error is triggered in the
if
branch of anif else
statement that does not invoke any of the code in fuel-vm.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 I talked about the error just before in the sentence I just added this parenthesis with the opcode in case we want to find later to have beteer search results