Eliminate some more transmute()
(#8879)
* eliminate some more transmute() * Address `review comments` * Make unsafe block smaller * Use different byte-order than `std`, read words as big endian instead of little endian! * Fix IpAddresses nits * Use `from_be` to work both for big and little endian * Ipv6 addresses were incorrectly `transmuted` * remove needless lifetime annotation
This commit is contained in:
parent
5ae8e8a9ca
commit
0cd1de769b
@ -137,11 +137,11 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
|||||||
($n:expr, $value:expr) => {{
|
($n:expr, $value:expr) => {{
|
||||||
// We use explicit lifetimes to ensure that val's borrow is invalidated until the
|
// We use explicit lifetimes to ensure that val's borrow is invalidated until the
|
||||||
// transmuted val dies.
|
// transmuted val dies.
|
||||||
unsafe fn make_const_array<'a, T, U>(val: &'a mut [T]) -> &'a mut [U; $n] {
|
unsafe fn make_const_array<T, U>(val: &mut [T]) -> &mut [U; $n] {
|
||||||
use ::std::mem;
|
use ::std::mem;
|
||||||
|
|
||||||
debug_assert_eq!(val.len() * mem::size_of::<T>(), $n * mem::size_of::<U>());
|
debug_assert_eq!(val.len() * mem::size_of::<T>(), $n * mem::size_of::<U>());
|
||||||
mem::transmute(val.as_mut_ptr())
|
&mut *(val.as_mut_ptr() as *mut [U; $n])
|
||||||
}
|
}
|
||||||
|
|
||||||
make_const_array($value)
|
make_const_array($value)
|
||||||
@ -177,7 +177,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
|||||||
|
|
||||||
ptr::copy_nonoverlapping(header_hash.as_ptr(), out.as_mut_ptr(), header_hash.len());
|
ptr::copy_nonoverlapping(header_hash.as_ptr(), out.as_mut_ptr(), header_hash.len());
|
||||||
ptr::copy_nonoverlapping(
|
ptr::copy_nonoverlapping(
|
||||||
mem::transmute(&nonce),
|
&nonce as *const u64 as *const u8,
|
||||||
out[header_hash.len()..].as_mut_ptr(),
|
out[header_hash.len()..].as_mut_ptr(),
|
||||||
mem::size_of::<u64>(),
|
mem::size_of::<u64>(),
|
||||||
);
|
);
|
||||||
@ -266,18 +266,20 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
|||||||
|
|
||||||
let mix_hash = buf.compress_bytes;
|
let mix_hash = buf.compress_bytes;
|
||||||
|
|
||||||
let value: H256 = unsafe {
|
let value: H256 = {
|
||||||
// We can interpret the buffer as an array of `u8`s, since it's `repr(C)`.
|
// We can interpret the buffer as an array of `u8`s, since it's `repr(C)`.
|
||||||
let read_ptr: *const u8 = mem::transmute(&buf);
|
let read_ptr: *const u8 = &buf as *const MixBuf as *const u8;
|
||||||
// We overwrite the second half since `keccak_256` has an internal buffer and so allows
|
// We overwrite the second half since `keccak_256` has an internal buffer and so allows
|
||||||
// overlapping arrays as input.
|
// overlapping arrays as input.
|
||||||
let write_ptr: *mut u8 = mem::transmute(&mut buf.compress_bytes);
|
let write_ptr: *mut u8 = &mut buf.compress_bytes as *mut [u8; 32] as *mut u8;
|
||||||
|
unsafe {
|
||||||
keccak_256::unchecked(
|
keccak_256::unchecked(
|
||||||
write_ptr,
|
write_ptr,
|
||||||
buf.compress_bytes.len(),
|
buf.compress_bytes.len(),
|
||||||
read_ptr,
|
read_ptr,
|
||||||
buf.half_mix.bytes.len() + buf.compress_bytes.len(),
|
buf.half_mix.bytes.len() + buf.compress_bytes.len(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
buf.compress_bytes
|
buf.compress_bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV
|
|||||||
use std::io;
|
use std::io;
|
||||||
use igd::{PortMappingProtocol, search_gateway_from_timeout};
|
use igd::{PortMappingProtocol, search_gateway_from_timeout};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use node_table::{NodeEndpoint};
|
use node_table::NodeEndpoint;
|
||||||
use ipnetwork::{IpNetwork};
|
use ipnetwork::IpNetwork;
|
||||||
|
|
||||||
/// Socket address extension for rustc beta. To be replaces with now unstable API
|
/// Socket address extension for rustc beta. To be replaces with now unstable API
|
||||||
pub trait SocketAddrExt {
|
pub trait SocketAddrExt {
|
||||||
@ -225,28 +225,17 @@ mod getinterfaces {
|
|||||||
let sa: *const sockaddr_in = sa as *const sockaddr_in;
|
let sa: *const sockaddr_in = sa as *const sockaddr_in;
|
||||||
let sa = unsafe { &*sa };
|
let sa = unsafe { &*sa };
|
||||||
let (addr, port) = (sa.sin_addr.s_addr, sa.sin_port);
|
let (addr, port) = (sa.sin_addr.s_addr, sa.sin_port);
|
||||||
(IpAddr::V4(Ipv4Addr::new(
|
// convert u32 to an `Ipv4 address`, but the u32 must be converted to `host-order`
|
||||||
(addr & 0x0000_00FF) as u8,
|
// that's why `from_be` is used!
|
||||||
((addr & 0x0000_FF00) >> 8) as u8,
|
(IpAddr::V4(Ipv4Addr::from(<u32>::from_be(addr))), port)
|
||||||
((addr & 0x00FF_0000) >> 16) as u8,
|
|
||||||
((addr & 0xFF00_0000) >> 24) as u8)),
|
|
||||||
port)
|
|
||||||
},
|
},
|
||||||
AF_INET6 => {
|
AF_INET6 => {
|
||||||
let sa: *const sockaddr_in6 = sa as *const sockaddr_in6;
|
let sa: *const sockaddr_in6 = sa as *const sockaddr_in6;
|
||||||
let sa = & unsafe { *sa };
|
let sa = & unsafe { *sa };
|
||||||
let (addr, port) = (sa.sin6_addr.s6_addr, sa.sin6_port);
|
let (addr, port) = (sa.sin6_addr.s6_addr, sa.sin6_port);
|
||||||
let addr: [u16; 8] = unsafe { mem::transmute(addr) };
|
let ip_addr = Ipv6Addr::from(addr);
|
||||||
(IpAddr::V6(Ipv6Addr::new(
|
debug_assert!(addr == ip_addr.octets());
|
||||||
addr[0],
|
(IpAddr::V6(ip_addr), port)
|
||||||
addr[1],
|
|
||||||
addr[2],
|
|
||||||
addr[3],
|
|
||||||
addr[4],
|
|
||||||
addr[5],
|
|
||||||
addr[6],
|
|
||||||
addr[7])),
|
|
||||||
port)
|
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user