Merge branch 'next' into feat/get-pox-addrs

This commit is contained in:
Jude Nelson
2022-08-09 15:01:57 -04:00
43 changed files with 8065 additions and 1873 deletions

View File

@@ -74,20 +74,17 @@ pub struct LoneBlockHeader {
impl BlockHeader {
/// Computes the target [0, T] that a blockhash must land in to be valid
pub fn target(&self) -> Uint256 {
pub fn compact_target_to_u256(bits: u32) -> Uint256 {
// This is a floating-point "compact" encoding originally used by
// OpenSSL, which satoshi put into consensus code, so we're stuck
// with it. The exponent needs to have 3 subtracted from it, hence
// this goofy decoding code:
let (mant, expt) = {
let unshifted_expt = self.bits >> 24;
let unshifted_expt = bits >> 24;
if unshifted_expt <= 3 {
(
(self.bits & 0xFFFFFF) >> (8 * (3 - unshifted_expt as usize)),
0,
)
((bits & 0xFFFFFF) >> (8 * (3 - unshifted_expt as usize)), 0)
} else {
(self.bits & 0xFFFFFF, 8 * ((self.bits >> 24) - 3))
(bits & 0xFFFFFF, 8 * ((bits >> 24) - 3))
}
};
@@ -99,6 +96,11 @@ impl BlockHeader {
}
}
/// Computes the target [0, T] that a blockhash must land in to be valid
pub fn target(&self) -> Uint256 {
BlockHeader::compact_target_to_u256(self.bits)
}
/// Computes the target value in float format from Uint256 format.
pub fn compact_target_from_u256(value: &Uint256) -> u32 {
let mut size = (value.bits() + 7) / 8;

View File

@@ -26,6 +26,7 @@ use std::time::{Duration, SystemTime};
lazy_static! {
pub static ref LOGGER: Logger = make_logger();
pub static ref STACKS_LOG_FORMAT_TIME: Option<String> = env::var("STACKS_LOG_FORMAT_TIME").ok();
}
struct TermFormat<D: Decorator> {
decorator: D,
@@ -41,15 +42,24 @@ fn print_msg_header(mut rd: &mut dyn RecordDecorator, record: &Record) -> io::Re
write!(rd, " ")?;
rd.start_timestamp()?;
let elapsed = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(Duration::from_secs(0));
write!(
rd,
"[{:5}.{:06}]",
elapsed.as_secs(),
elapsed.subsec_nanos() / 1000
)?;
let system_time = SystemTime::now();
match &*STACKS_LOG_FORMAT_TIME {
None => {
let elapsed = system_time
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(Duration::from_secs(0));
write!(
rd,
"[{:5}.{:06}]",
elapsed.as_secs(),
elapsed.subsec_nanos() / 1000
)?;
}
Some(ref format) => {
let datetime: DateTime<Local> = system_time.into();
write!(rd, "[{}]", datetime.format(format))?;
}
}
write!(rd, " ")?;
write!(rd, "[{}:{}]", record.file(), record.line())?;
write!(rd, " ")?;

View File

@@ -19,6 +19,7 @@
//! Implementation of a various large-but-fixed sized unsigned integer types.
//! The functions here are designed to be fast.
//!
use crate::util::hash::{hex_bytes, to_hex};
/// Borrowed with gratitude from Andrew Poelstra's rust-bitcoin library
use std::fmt;
@@ -130,7 +131,7 @@ macro_rules! construct_uint {
$name(ret)
}
/// as byte array
/// as litte-endian byte array
pub fn to_u8_slice(&self) -> [u8; $n_words * 8] {
let mut ret = [0u8; $n_words * 8];
for i in 0..$n_words {
@@ -141,6 +142,67 @@ macro_rules! construct_uint {
}
ret
}
/// as big-endian byte array
pub fn to_u8_slice_be(&self) -> [u8; $n_words * 8] {
let mut ret = [0u8; $n_words * 8];
for i in 0..$n_words {
let word_end = $n_words * 8 - (i * 8);
let word_start = word_end - 8;
ret[word_start..word_end].copy_from_slice(&self.0[i].to_be_bytes());
}
ret
}
/// from a little-endian hex string
/// padding is expected
pub fn from_hex_le(hex: &str) -> Option<$name> {
let bytes = hex_bytes(hex).ok()?;
if bytes.len() % 8 != 0 {
return None;
}
if bytes.len() / 8 != $n_words {
return None;
}
let mut ret = [0u64; $n_words];
for i in 0..(bytes.len() / 8) {
let mut next_bytes = [0u8; 8];
next_bytes.copy_from_slice(&bytes[8 * i..(8 * (i + 1))]);
let next = u64::from_le_bytes(next_bytes);
ret[i] = next;
}
Some($name(ret))
}
/// to a little-endian hex string
pub fn to_hex_le(&self) -> String {
to_hex(&self.to_u8_slice())
}
/// from a big-endian hex string
/// padding is expected
pub fn from_hex_be(hex: &str) -> Option<$name> {
let bytes = hex_bytes(hex).ok()?;
if bytes.len() % 8 != 0 {
return None;
}
if bytes.len() / 8 != $n_words {
return None;
}
let mut ret = [0u64; $n_words];
for i in 0..(bytes.len() / 8) {
let mut next_bytes = [0u8; 8];
next_bytes.copy_from_slice(&bytes[8 * i..(8 * (i + 1))]);
let next = u64::from_be_bytes(next_bytes);
ret[(bytes.len() / 8) - 1 - i] = next;
}
Some($name(ret))
}
/// to a big-endian hex string
pub fn to_hex_be(&self) -> String {
to_hex(&self.to_u8_slice_be())
}
}
impl ::std::ops::Add<$name> for $name {
@@ -671,4 +733,22 @@ mod tests {
Uint256([0, 0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0])
);
}
#[test]
pub fn hex_codec() {
let init =
Uint256::from_u64(0xDEADBEEFDEADBEEF) << 64 | Uint256::from_u64(0x0102030405060708);
// little-endian representation
let hex_init = "0807060504030201efbeaddeefbeadde00000000000000000000000000000000";
assert_eq!(Uint256::from_hex_le(&hex_init).unwrap(), init);
assert_eq!(&init.to_hex_le(), hex_init);
assert_eq!(Uint256::from_hex_le(&init.to_hex_le()).unwrap(), init);
// big-endian representation
let hex_init = "00000000000000000000000000000000deadbeefdeadbeef0102030405060708";
assert_eq!(Uint256::from_hex_be(&hex_init).unwrap(), init);
assert_eq!(&init.to_hex_be(), hex_init);
assert_eq!(Uint256::from_hex_be(&init.to_hex_be()).unwrap(), init);
}
}