mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 05:44:44 +00:00
Rename eth2_bytes to int_to_bytes
This commit is contained in:
125
eth2/utils/int_to_bytes/src/lib.rs
Normal file
125
eth2/utils/int_to_bytes/src/lib.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 1.
|
||||
pub fn int_to_bytes1(int: u8) -> Vec<u8> {
|
||||
vec![int]
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 2.
|
||||
pub fn int_to_bytes2(int: u16) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(2);
|
||||
bytes.put_u16_le(int);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 3.
|
||||
///
|
||||
/// An `Option` is returned as Rust does not support a native
|
||||
/// `u24` type.
|
||||
///
|
||||
/// The Eth 2.0 specification uses `int.to_bytes(2, 'little')`, which throws an error if `int`
|
||||
/// doesn't fit within 3 bytes. The specification relies upon implicit asserts for some validity
|
||||
/// conditions, so we ensure the calling function is aware of the error condition as opposed to
|
||||
/// hiding it with a modulo.
|
||||
pub fn int_to_bytes3(int: u32) -> Option<Vec<u8>> {
|
||||
if int < 2_u32.pow(3 * 8) {
|
||||
let mut bytes = BytesMut::with_capacity(4);
|
||||
bytes.put_u32_le(int);
|
||||
Some(bytes[0..3].to_vec())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 4.
|
||||
pub fn int_to_bytes4(int: u32) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(4);
|
||||
bytes.put_u32_le(int);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 8.
|
||||
pub fn int_to_bytes8(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(8);
|
||||
bytes.put_u64_le(int);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 32.
|
||||
pub fn int_to_bytes32(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(32);
|
||||
bytes.put_u64_le(int);
|
||||
bytes.resize(32, 0);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 48.
|
||||
pub fn int_to_bytes48(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(48);
|
||||
bytes.put_u64_le(int);
|
||||
bytes.resize(48, 0);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns `int` as little-endian bytes with a length of 96.
|
||||
pub fn int_to_bytes96(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(96);
|
||||
bytes.put_u64_le(int);
|
||||
bytes.resize(96, 0);
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use hex;
|
||||
use std::{fs::File, io::prelude::*, path::PathBuf};
|
||||
use yaml_rust::yaml;
|
||||
|
||||
#[test]
|
||||
fn int_to_bytes3_returns_none() {
|
||||
assert_eq!(int_to_bytes3(2_u32.pow(24)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vectors() {
|
||||
/*
|
||||
* Test vectors are generated here:
|
||||
*
|
||||
* https://github.com/ethereum/eth2.0-test-generators
|
||||
*/
|
||||
let mut file = {
|
||||
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
file_path_buf.push("src/specs/test_vector_int_to_bytes.yml");
|
||||
|
||||
File::open(file_path_buf).unwrap()
|
||||
};
|
||||
|
||||
let mut yaml_str = String::new();
|
||||
|
||||
file.read_to_string(&mut yaml_str).unwrap();
|
||||
|
||||
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
|
||||
let doc = &docs[0];
|
||||
let test_cases = doc["test_cases"].as_vec().unwrap();
|
||||
|
||||
for test_case in test_cases {
|
||||
let byte_length = test_case["byte_length"].as_i64().unwrap() as u64;
|
||||
let int = test_case["int"].as_i64().unwrap() as u64;
|
||||
let bytes_string = test_case["bytes"].clone().into_string().unwrap();
|
||||
let bytes = hex::decode(bytes_string.replace("0x", "")).unwrap();
|
||||
|
||||
match byte_length {
|
||||
1 => assert_eq!(int_to_bytes1(int as u8), bytes),
|
||||
2 => assert_eq!(int_to_bytes2(int as u16), bytes),
|
||||
3 => assert_eq!(int_to_bytes3(int as u32), Some(bytes)),
|
||||
4 => assert_eq!(int_to_bytes4(int as u32), bytes),
|
||||
8 => assert_eq!(int_to_bytes8(int), bytes),
|
||||
32 => assert_eq!(int_to_bytes32(int), bytes),
|
||||
48 => assert_eq!(int_to_bytes48(int), bytes),
|
||||
96 => assert_eq!(int_to_bytes96(int), bytes),
|
||||
_ => panic!("Unknown byte length in test vector."),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user