-
Notifications
You must be signed in to change notification settings - Fork 795
Conversation
ethers-core/src/abi/packed.rs
Outdated
Int(n) | Uint(n) => { | ||
// TODO: Different (u)int* padding | ||
let mut buf = [0; 32]; | ||
n.to_big_endian(&mut buf); | ||
out.extend_from_slice(&buf); | ||
} |
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.
By using the same Token
type as ethabi
, we cannot differentiate between the different integer type sizes as Token::(U)Int
stores only the U256
number and not its encoded size (since in normal abi-encoding this wouldn't have any effect).
Should this function use a different Token
-like enum, or is there another way around this?
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 can find the smallest value for which n >> BITS
is 0, and mark that as the size?
e.g.
255 >> 8 == 0 --> put it in uint8
whereas 256 >> 8 == 1, putting it in uint16
etc.
maybe we have that logic somewhere in reth's compact encoding
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.
Right, but how does one then cast the number as something higher than its minimum bits? Like uint256(0) would need to pad all 32 bytes? We can have this as a minor limitation for the time being I guess
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.
Implemented this using U256::bits
. Any 0 padding needs to be manually added with something like this:
let n = U256::from(...);
let mut buf = [0; 32];
n.to_big_endian(&mut buf);
// uint32 = 4 bytes -> 32 - 4 .. 32
let uint32 = Token::Bytes(buf[28..32]);
LGTM - ty!! |
Motivation
Closes #1862
Solution
PR Checklist