Skip to content

Commit c1dca72

Browse files
committed
use more EVM style params for precompiles
1 parent eea22e0 commit c1dca72

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

actors/evm/src/interpreter/precompiles.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,50 +103,51 @@ fn read_right_pad<'a>(input: impl Into<Cow<'a, [u8]>>, len: usize) -> Cow<'a, [u
103103

104104
// --- Precompiles ---
105105

106-
/// Read right padded BE encoded u64 ID address
106+
/// Read right padded BE encoded low u64 ID address from a u256 word
107107
/// returns encoded CID or an empty array if actor not found
108108
fn get_actor_code_cid<RT: Runtime>(rt: &RT, input: &[u8]) -> PrecompileResult {
109-
let id_bytes = read_right_pad(input, 8);
110-
let id = u64::from_be_bytes(id_bytes.as_ref().try_into().unwrap());
109+
let id_bytes = read_right_pad(input, 32);
110+
let id = U256::from_big_endian(&id_bytes).low_u64();
111111
Ok(rt.get_actor_code_cid(&id).unwrap_or_default().to_bytes())
112112
}
113113

114114
/// Params:
115115
///
116-
/// | Param | Value | Byte Length |
117-
/// |------------------|---------------------------|---|
118-
/// | randomness_type | `Chain`(0) OR `Beacon`(1) | 1 |
119-
/// | RESERVED | must be zeroes | 7 |
120-
/// | personalization | `i64` (LE encoded) | 8 |
121-
/// | randomness_epoch | `i64` (LE encoded) | 8 |
122-
/// | entropy_length | `u64` (LE encoded) | 8 |
123-
/// | entropy | input\[32..] (right padded)| entropy_length |
116+
/// | Param | Value |
117+
/// |------------------|---------------------------|
118+
/// | randomness_type | U256 - low i32: `Chain`(0) OR `Beacon`(1) |
119+
/// | personalization | U256 - low i64 |
120+
/// | randomness_epoch | U256 - low i64 |
121+
/// | entropy_length | U256 - low u64 |
122+
/// | entropy | input\[32..] (right padded)|
123+
///
124+
/// any bytes in between values are ignored
124125
///
125126
/// Returns empty array if invalid randomness type
126-
/// Errors if unable to fetch randomness or bits are in reserved zone
127+
/// Errors if unable to fetch randomness
127128
fn get_randomness<RT: Runtime>(rt: &RT, input: &[u8]) -> PrecompileResult {
128-
// 1 + 7 (reserved) + 8 + 8 + 8 = 32
129-
let word = read_right_pad(input, 32);
129+
// 32 * 4 = 128
130+
let input = read_right_pad(input, 128);
130131

131132
#[derive(num_derive::FromPrimitive)]
132-
#[repr(u8)]
133+
#[repr(i32)]
133134
enum RandomnessType {
134135
Chain = 0,
135136
Beacon = 1,
136137
}
137138

138-
let randomness_type = RandomnessType::from_u8(word[0]);
139+
let randomness_word = &input[0..32];
140+
let personalization_bytes = &input[32..64];
141+
let epoch_bytes = &input[64..96];
142+
let entropy_len_bytes = &input[96..128];
139143

140-
// 7 bytes reserved
141-
if word[1..8] != [0u8; 7] {
142-
return Err(PrecompileError::InvalidInput);
143-
}
144144

145-
let personalization = i64::from_le_bytes(word[8..16].try_into().unwrap());
146-
let rand_epoch = i64::from_le_bytes(word[16..24].try_into().unwrap());
147-
let entropy_len = u64::from_le_bytes(word[24..32].try_into().unwrap());
145+
let randomness_type = RandomnessType::from_i32(i32::from_be_bytes(randomness_word[28..32].try_into().unwrap()));
146+
let personalization = i64::from_be_bytes(personalization_bytes[24..32].try_into().unwrap());
147+
let rand_epoch = i64::from_be_bytes(epoch_bytes[24..32].try_into().unwrap());
148+
let entropy_len = u64::from_be_bytes(entropy_len_bytes[24..32].try_into().unwrap());
148149

149-
let entropy = read_right_pad(&input[32..], entropy_len as usize);
150+
let entropy = read_right_pad(&input[128..], entropy_len as usize);
150151

151152
let randomness = match randomness_type {
152153
Some(RandomnessType::Chain) => rt
@@ -161,11 +162,11 @@ fn get_randomness<RT: Runtime>(rt: &RT, input: &[u8]) -> PrecompileResult {
161162
randomness.map_err(|_| PrecompileError::InvalidInput)
162163
}
163164

164-
/// Reads right padded BE encoded u64
165+
/// Read right padded BE encoded low u64 ID address from a u256 word
165166
/// Looks up and returns the other address (encoded f2 or f4 addresses) of an ID address, returning empty array if not found
166167
fn lookup_address<RT: Runtime>(rt: &RT, input: &[u8]) -> PrecompileResult {
167-
let id_bytes = read_right_pad(input, 8);
168-
let id = u64::from_be_bytes(id_bytes.as_ref().try_into().unwrap());
168+
let id_bytes = read_right_pad(input, 32);
169+
let id = U256::from_big_endian(&id_bytes).low_u64();
169170

170171
let address = rt.lookup_address(id);
171172
let ab = match address {

0 commit comments

Comments
 (0)