-
Notifications
You must be signed in to change notification settings - Fork 91
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
Include size lookup of contract for computing LDC opcode cost #598
Conversation
It looks like the storage allows getting the contract bytes for a specified buffer, so we only copy what is specified with I've added a test that copies a contract with a bunch of Still might clean up these tests a bit. There is some DRYing I can do before merging this. |
fuel-vm/src/tests/blockchain.rs
Outdated
op::move_(reg_a, RegId::HP), // r[a] := $hp | ||
op::ldc(0x10, RegId::ZERO, reg_a), /* Load first two words from the | ||
* contract */ |
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.
The comment is incorrect here. This loads first $hp
bytes from the contract. The code should likely read like this:
op::move_(reg_a, RegId::HP), // r[a] := $hp | |
op::ldc(0x10, RegId::ZERO, reg_a), /* Load first two words from the | |
* contract */ | |
op::ldc(0x10, RegId::ZERO, RegId::HP), |
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.
Thanks. I think a lot of these are wrong, but I don't really understand them enough to fix them. I'm just copying what was already there.
Might be worth fixing all of them, maybe in another PR.
fuel-vm/src/tests/blockchain.rs
Outdated
op::ldc(0x10, RegId::ZERO, RegId::ZERO), /* Load first two words from * | ||
* the contract */ |
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 loads zero words from the contract, so the comment is incorrect. I suggest loading a single byte anyway, since this test shouldn't be hitting the zero-length-load corner case.
op::ldc(0x10, RegId::ZERO, RegId::ZERO), /* Load first two words from * | |
* the contract */ | |
op::ldc(0x10, RegId::ZERO, RegId::ONE), |
fuel-vm/src/tests/blockchain.rs
Outdated
op::move_(reg_a, RegId::SSP), // r[a] := $ssp | ||
op::subi(reg_a, reg_a, 16), // r[a] -= 16 (start of the loaded code) | ||
op::xor(reg_b, reg_b, reg_b), // r[b] := 0 | ||
op::addi(reg_b, reg_b, 16), // r[b] += 16 (length of the loaded code) |
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.
op::move_(reg_a, RegId::SSP), // r[a] := $ssp | |
op::subi(reg_a, reg_a, 16), // r[a] -= 16 (start of the loaded code) | |
op::xor(reg_b, reg_b, reg_b), // r[b] := 0 | |
op::addi(reg_b, reg_b, 16), // r[b] += 16 (length of the loaded code) | |
op::subi(reg_a, RegId::SSP, 16), // r[a] := $ssp - 16 (start of the loaded code) | |
op::movi(reg_b, 16), // r[b] = 16 (length of the loaded code) |
.into_owned() | ||
.into(); | ||
let contract_len = contract_bytes.len(); | ||
let contract_sub_bytes = |
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 thought it was already handled by copy_from_slice_zero_fill_noownerchecks
.
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. And reverting to using this fixes the test bug.
super::contract::contract(self.storage, &contract_id)? | ||
.into_owned() | ||
.into(); | ||
let contract_len = contract_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.
It would be nice to charge the user here before we do the main work.
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'll look into it. This would be quite the architectural change, I think, but if it's how it needs to work, then I'll make it work.
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.
K. I split the function in half to return the bytes and then copy them separately. I don't love the solution becuase the functions are doing too much, but it's probably better :)
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.
@MitchTurner I moved charging for the contract size into the load_contract_code
. It works in the same way as for code_size
.
If you are okay with it, then you can merge the PR=)
fuel-vm/src/tests/blockchain.rs
Outdated
op::ldc(reg_a, reg_b, reg_c), // Load first two words from the contract | ||
op::subi(reg_a, RegId::SSP, 16), /* r[a] := $ssp - 16 (start of the loaded | ||
* code) */ | ||
op::movi(reg_c, 16), // r[b] = 16 (length of the loaded code) | ||
op::logd(RegId::ZERO, RegId::ZERO, reg_a, reg_c), /* Log digest of the |
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 looks like you're loading len
bytes from the contract, given that len
is stored in reg_c
. In the tests, you pass 0
for len
, but the following opcodes hardcode 16
. If I understand correctly, ldc
still loads the whole contract regardless of length/$rC
, but I think the subi
, movi
, and logd
opcodes here become incorrect. Are they even necessary for these tests? Maybe we can remove them.
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 fails the ldc__load_external_contract_code
test without it.
But you're completely right. I think it just needs to be parameterized for the len
. It just so happens that the padded length for that test is 16 🤡
fuel-vm/src/tests/blockchain.rs
Outdated
op::subi(reg_a, RegId::SSP, padded_len), /* r[a] := $ssp - 16 (start of | ||
* the loaded | ||
* code) */ | ||
op::movi(reg_c, padded_len as u32), // r[b] = 16 (length of the loaded code) |
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.
Maybe you want to update a comment regarding 16
FuelLabs/fuel-core#1271