Merge branch 'master' of github.com:gavofyork/ethcore-util
This commit is contained in:
commit
1dae68cd05
28
src/bytes.rs
28
src/bytes.rs
@ -39,6 +39,7 @@ use std::fmt;
|
||||
use std::slice;
|
||||
use std::cmp::Ordering;
|
||||
use std::error::Error as StdError;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use uint::{U128, U256};
|
||||
use hash::FixedHash;
|
||||
|
||||
@ -89,6 +90,31 @@ impl ToPretty for Bytes {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum BytesRef<'a> {
|
||||
Flexible(&'a mut Bytes),
|
||||
Fixed(&'a mut [u8])
|
||||
}
|
||||
|
||||
impl<'a> Deref for BytesRef<'a> {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &[u8] {
|
||||
match self {
|
||||
&BytesRef::Flexible(ref bytes) => bytes,
|
||||
&BytesRef::Fixed(ref bytes) => bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> DerefMut for BytesRef<'a> {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
match self {
|
||||
&mut BytesRef::Flexible(ref mut bytes) => bytes,
|
||||
&mut BytesRef::Fixed(ref mut bytes) => bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Vector of bytes
|
||||
pub type Bytes = Vec<u8>;
|
||||
|
||||
@ -436,4 +462,4 @@ fn populate_big_types() {
|
||||
let mut h = h256_from_u64(0x69);
|
||||
h.copy_raw_from(&a);
|
||||
assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000069"));
|
||||
}
|
||||
}
|
||||
|
@ -5,3 +5,31 @@ pub use uint::*;
|
||||
pub use bytes::*;
|
||||
pub use vector::*;
|
||||
pub use sha3::*;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! map {
|
||||
( $( $x:expr => $y:expr ),* ) => {
|
||||
vec![ $( ($x, $y) ),* ].into_iter().collect::<BTreeMap<_, _>>()
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mapx {
|
||||
( $( $x:expr => $y:expr ),* ) => {
|
||||
vec![ $( ( From::from($x), From::from($y) ) ),* ].into_iter().collect::<BTreeMap<_, _>>()
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! x {
|
||||
( $x:expr ) => {
|
||||
From::from($x)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xx {
|
||||
( $x:expr ) => {
|
||||
From::from(From::from($x))
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,8 @@ impl KeyPair {
|
||||
|
||||
pub mod ec {
|
||||
use hash::*;
|
||||
use uint::*;
|
||||
use standard::*;
|
||||
use crypto::*;
|
||||
use crypto::{self};
|
||||
|
||||
@ -136,6 +138,7 @@ pub mod ec {
|
||||
}
|
||||
/// Returns siganture of message hash.
|
||||
pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> {
|
||||
// TODO: allow creation of only low-s signatures.
|
||||
use secp256k1::*;
|
||||
let context = Secp256k1::new();
|
||||
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
|
||||
@ -165,6 +168,16 @@ pub mod ec {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this is a "low" signature.
|
||||
pub fn is_low(sig: &Signature) -> bool {
|
||||
H256::from_slice(&sig[32..64]) <= h256_from_hex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0")
|
||||
}
|
||||
|
||||
/// Check if this is a "low" signature.
|
||||
pub fn is_low_s(s: &U256) -> bool {
|
||||
s <= &U256::from_str("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0").unwrap()
|
||||
}
|
||||
|
||||
/// Check if each component of the signature is in range.
|
||||
pub fn is_valid(sig: &Signature) -> bool {
|
||||
sig[64] <= 1 &&
|
||||
|
64
src/hash.rs
64
src/hash.rs
@ -35,6 +35,14 @@ pub trait FixedHash: Sized + BytesConvertable + Populatable {
|
||||
fn is_zero(&self) -> bool;
|
||||
}
|
||||
|
||||
fn clean_0x(s: &str) -> &str {
|
||||
if s.len() >= 2 && &s[0..2] == "0x" {
|
||||
&s[2..]
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_hash {
|
||||
($from: ident, $size: expr) => {
|
||||
#[derive(Eq)]
|
||||
@ -224,16 +232,22 @@ macro_rules! impl_hash {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for $from {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
impl Ord for $from {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
for i in 0..$size {
|
||||
if self.0[i] > other.0[i] {
|
||||
return Some(Ordering::Greater);
|
||||
return Ordering::Greater;
|
||||
} else if self.0[i] < other.0[i] {
|
||||
return Some(Ordering::Less);
|
||||
return Ordering::Less;
|
||||
}
|
||||
}
|
||||
Some(Ordering::Equal)
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for $from {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,6 +385,30 @@ macro_rules! impl_hash {
|
||||
|
||||
pub fn from_bloomed<T>(b: &T) -> Self where T: FixedHash { b.bloom_part($size) }
|
||||
}
|
||||
|
||||
impl From<u64> for $from {
|
||||
fn from(mut value: u64) -> $from {
|
||||
let mut ret = $from::new();
|
||||
for i in 0..8 {
|
||||
if i < $size {
|
||||
ret.0[$size - i - 1] = (value & 0xff) as u8;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl<'_> From<&'_ str> for $from {
|
||||
fn from(s: &'_ str) -> $from {
|
||||
use std::str::FromStr;
|
||||
if s.len() % 2 == 1 {
|
||||
$from::from_str(&("0".to_string() + &(clean_0x(s).to_string()))[..]).unwrap_or($from::new())
|
||||
} else {
|
||||
$from::from_str(clean_0x(s)).unwrap_or($from::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,5 +537,21 @@ mod tests {
|
||||
let a = Address::from(h);
|
||||
assert_eq!(address, a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_u64() {
|
||||
assert_eq!(H128::from(0x1234567890abcdef), H128::from_str("00000000000000001234567890abcdef").unwrap());
|
||||
assert_eq!(H64::from(0x1234567890abcdef), H64::from_str("1234567890abcdef").unwrap());
|
||||
assert_eq!(H32::from(0x1234567890abcdef), H32::from_str("90abcdef").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(H64::from(0x1234567890abcdef), H64::from("0x1234567890abcdef"));
|
||||
assert_eq!(H64::from(0x1234567890abcdef), H64::from("1234567890abcdef"));
|
||||
assert_eq!(H64::from(0x234567890abcdef), H64::from("0x234567890abcdef"));
|
||||
// too short.
|
||||
assert_eq!(H64::from(0), H64::from("0x34567890abcdef"));
|
||||
}
|
||||
}
|
||||
|
||||
|
63
src/json_aid.rs
Normal file
63
src/json_aid.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use common::*;
|
||||
|
||||
pub fn clean(s: &str) -> &str {
|
||||
if s.len() >= 2 && &s[0..2] == "0x" {
|
||||
&s[2..]
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_from_json(json: &Json) -> Bytes {
|
||||
let s = json.as_string().unwrap_or("");
|
||||
if s.len() % 2 == 1 {
|
||||
FromHex::from_hex(&("0".to_string() + &(clean(s).to_string()))[..]).unwrap_or(vec![])
|
||||
} else {
|
||||
FromHex::from_hex(clean(s)).unwrap_or(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn address_from_json(json: &Json) -> Address {
|
||||
From::from(json.as_string().unwrap_or("0000000000000000000000000000000000000000"))
|
||||
}
|
||||
|
||||
pub fn h256_from_json(json: &Json) -> H256 {
|
||||
let s = json.as_string().unwrap_or("0000000000000000000000000000000000000000000000000000000000000000");
|
||||
if s.len() % 2 == 1 {
|
||||
h256_from_hex(&("0".to_string() + &(clean(s).to_string()))[..])
|
||||
} else {
|
||||
h256_from_hex(clean(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn u256_from_str(s: &str) -> U256 {
|
||||
if s.len() >= 2 && &s[0..2] == "0x" {
|
||||
U256::from_str(&s[2..]).unwrap_or(U256::from(0))
|
||||
} else {
|
||||
U256::from_dec_str(s).unwrap_or(U256::from(0))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn u256_from_json(json: &Json) -> U256 {
|
||||
u256_from_str(json.as_string().unwrap_or(""))
|
||||
}
|
||||
|
||||
pub fn usize_from_json(json: &Json) -> usize {
|
||||
u256_from_json(json).low_u64() as usize
|
||||
}
|
||||
|
||||
pub fn u64_from_json(json: &Json) -> u64 {
|
||||
u256_from_json(json).low_u64()
|
||||
}
|
||||
|
||||
pub fn u32_from_json(json: &Json) -> u32 {
|
||||
u256_from_json(json).low_u32()
|
||||
}
|
||||
|
||||
pub fn u16_from_json(json: &Json) -> u16 {
|
||||
u256_from_json(json).low_u32() as u16
|
||||
}
|
||||
|
||||
pub fn u8_from_json(json: &Json) -> u8 {
|
||||
u256_from_json(json).low_u32() as u8
|
||||
}
|
@ -57,6 +57,7 @@ pub mod hash;
|
||||
pub mod uint;
|
||||
pub mod bytes;
|
||||
pub mod rlp;
|
||||
pub mod json_aid;
|
||||
pub mod vector;
|
||||
pub mod sha3;
|
||||
pub mod hashdb;
|
||||
@ -74,6 +75,7 @@ pub mod semantic_version;
|
||||
pub mod network;
|
||||
|
||||
pub use common::*;
|
||||
pub use json_aid::*;
|
||||
pub use rlp::*;
|
||||
pub use hashdb::*;
|
||||
pub use memorydb::*;
|
||||
|
@ -9,6 +9,9 @@ pub enum DecoderError {
|
||||
RlpExpectedToBeList,
|
||||
RlpExpectedToBeData,
|
||||
RlpIncorrectListLen,
|
||||
RlpDataLenWithZeroPrefix,
|
||||
RlpListLenWithZeroPrefix,
|
||||
RlpInvalidIndirection,
|
||||
}
|
||||
|
||||
impl StdError for DecoderError {
|
||||
|
@ -269,6 +269,7 @@ impl<'a> BasicDecoder<'a> {
|
||||
Some(l @ 0xb8...0xbf) => {
|
||||
let len_of_len = l as usize - 0xb7;
|
||||
let header_len = 1 + len_of_len;
|
||||
if bytes[1] == 0 { return Err(DecoderError::RlpDataLenWithZeroPrefix); }
|
||||
let value_len = try!(usize::from_bytes(&bytes[1..header_len]));
|
||||
PayloadInfo::new(header_len, value_len)
|
||||
}
|
||||
@ -277,6 +278,7 @@ impl<'a> BasicDecoder<'a> {
|
||||
let len_of_len = l as usize - 0xf7;
|
||||
let header_len = 1 + len_of_len;
|
||||
let value_len = try!(usize::from_bytes(&bytes[1..header_len]));
|
||||
if bytes[1] == 0 { return Err(DecoderError::RlpListLenWithZeroPrefix); }
|
||||
PayloadInfo::new(header_len, value_len)
|
||||
},
|
||||
// we cant reach this place, but rust requires _ to be implemented
|
||||
@ -302,7 +304,13 @@ impl<'a> Decoder for BasicDecoder<'a> {
|
||||
// single byt value
|
||||
Some(l @ 0...0x7f) => Ok(try!(f(&[l]))),
|
||||
// 0-55 bytes
|
||||
Some(l @ 0x80...0xb7) => Ok(try!(f(&bytes[1..(1 + l as usize - 0x80)]))),
|
||||
Some(l @ 0x80...0xb7) => {
|
||||
let d = &bytes[1..(1 + l as usize - 0x80)];
|
||||
if l == 0x81 && d[0] < 0x80 {
|
||||
return Err(DecoderError::RlpInvalidIndirection);
|
||||
}
|
||||
Ok(try!(f(d)))
|
||||
},
|
||||
// longer than 55 bytes
|
||||
Some(l @ 0xb8...0xbf) => {
|
||||
let len_of_len = l as usize - 0xb7;
|
||||
|
Loading…
Reference in New Issue
Block a user