-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Handle ReturnData
for other types
#161
Conversation
let res = contract_instance.get_contract_id().call().await.unwrap(); | ||
|
||
// First `value` is from `CallResponse`. | ||
// Second `value` is from Sway `ContractId` type. | ||
assert_eq!( | ||
res.value.value, | ||
[ | ||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | ||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 | ||
] | ||
); |
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.
@nfurfaro I believe this is the relevant case for you: get_contract_id()
returns the Sway type ContractId
, which wraps the b256
in a Struct
, which wasn't being handled before. Now it seems to be working fine!
match &*self { | ||
// Bits256 Always bigger than one `WORD`. | ||
Self::B256 => true, | ||
Self::String(size) => size > 8, | ||
// Strings are bigger than one `WORD` when its size > 8. | ||
Self::String(size) => size > &8, | ||
Self::Struct(params) => match params.len() { | ||
// If only one component in this struct | ||
// check if this element itself is bigger than a `WORD`. | ||
1 => params[0].bigger_than_word(), | ||
_ => true, | ||
}, | ||
// Enums are always in `ReturnData`. | ||
Self::Enum(_params) => true, | ||
// Arrays seem to always be inside `ReturnData`. | ||
Self::Array(_params, _l) => true, | ||
// The other primitive types are inside `Return`, | ||
// thus smaller than one `WORD`. | ||
_ => false, |
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.
@vnepveu I believe this will be related to your current work on supporting multiple return values, make sure to rebase it on top of this once it's merged!
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 will do!
ReturnData
for other typesReturnData
for other types
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, but I'll defer to @vnepveu
}, | ||
// Enums are always in `ReturnData`. | ||
Self::Enum(_params) => true, | ||
// Arrays seem to always be inside `ReturnData`. |
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.
Is this expected or a bug? cc @otrho
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 guessing at this stage it's always true since even an enum with a single variant will still have a tag and a value, even if it's just unit
. So it can't fit in a register. After we add some gnarly optimisations this may no longer be true, but only if we want to go there.
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 I was pointing at the Arrays seem to always be inside `ReturnData`.
, not the enums 😂
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.
Unfortunately I had to do a lot of guesswork to get this working and figure out where each returned type would be located at.
As for arrays, in the tests I did, they were always in ReturnData (there are few new array-as-output tests added in this PR). But then again, I didn't fuzz or anything, just tested a few cases and focused on solving some existing blockers.
But, intuitively (which could be wrong of course), if any primitive type takes a whole word. Even if it doesn't fill it all we pad it. So an array should be larger than a word? Maybe unless is an array of size zero or 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.
An array of size 0 or 1 should only take up a single word. Could you add a test for that @digorithm?
Co-authored-by: John Adler <[email protected]>
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
match &*self { | ||
// Bits256 Always bigger than one `WORD`. | ||
Self::B256 => true, | ||
Self::String(size) => size > 8, | ||
// Strings are bigger than one `WORD` when its size > 8. | ||
Self::String(size) => size > &8, | ||
Self::Struct(params) => match params.len() { | ||
// If only one component in this struct | ||
// check if this element itself is bigger than a `WORD`. | ||
1 => params[0].bigger_than_word(), | ||
_ => true, | ||
}, | ||
// Enums are always in `ReturnData`. | ||
Self::Enum(_params) => true, | ||
// Arrays seem to always be inside `ReturnData`. | ||
Self::Array(_params, _l) => true, | ||
// The other primitive types are inside `Return`, | ||
// thus smaller than one `WORD`. | ||
_ => false, |
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 will do!
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.
Can handle arrays of size 0 or 1 in a future PR. Make sure there's an issue for it.
Tracking it here: #162. |
Closes #139.
More context in #139. Summary: depending on the size of the returned data, the returned data will live either under the
Return
receipt orReturnData
receipt. This handles it for the types that weren't being properly handled before.