Fix RLP on consensus.

Add JSON helpers.
This commit is contained in:
Gav Wood 2016-01-12 23:44:30 +01:00
parent 6b1eb943e2
commit 635bf284b4
5 changed files with 92 additions and 1 deletions

View File

@ -120,6 +120,8 @@ impl KeyPair {
pub mod ec { pub mod ec {
use hash::*; use hash::*;
use uint::*;
use standard::*;
use crypto::*; use crypto::*;
use crypto::{self}; use crypto::{self};
@ -136,6 +138,7 @@ pub mod ec {
} }
/// Returns siganture of message hash. /// Returns siganture of message hash.
pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> { pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> {
// TODO: allow creation of only low-s signatures.
use secp256k1::*; use secp256k1::*;
let context = Secp256k1::new(); let context = Secp256k1::new();
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) }; 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. /// Check if each component of the signature is in range.
pub fn is_valid(sig: &Signature) -> bool { pub fn is_valid(sig: &Signature) -> bool {
sig[64] <= 1 && sig[64] <= 1 &&

65
src/json_aid.rs Normal file
View File

@ -0,0 +1,65 @@
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 {
let s = json.as_string().unwrap_or("0000000000000000000000000000000000000000");
if s.len() % 2 == 1 {
address_from_hex(&("0".to_string() + &(clean(s).to_string()))[..])
} else {
address_from_hex(clean(s))
}
}
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_json(json: &Json) -> U256 {
let s = json.as_string().unwrap_or("");
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 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
}

View File

@ -57,6 +57,7 @@ pub mod hash;
pub mod uint; pub mod uint;
pub mod bytes; pub mod bytes;
pub mod rlp; pub mod rlp;
pub mod json_aid;
pub mod vector; pub mod vector;
pub mod sha3; pub mod sha3;
pub mod hashdb; pub mod hashdb;
@ -74,6 +75,7 @@ pub mod semantic_version;
pub mod network; pub mod network;
pub use common::*; pub use common::*;
pub use json_aid::*;
pub use rlp::*; pub use rlp::*;
pub use hashdb::*; pub use hashdb::*;
pub use memorydb::*; pub use memorydb::*;

View File

@ -9,6 +9,9 @@ pub enum DecoderError {
RlpExpectedToBeList, RlpExpectedToBeList,
RlpExpectedToBeData, RlpExpectedToBeData,
RlpIncorrectListLen, RlpIncorrectListLen,
RlpDataLenWithZeroPrefix,
RlpListLenWithZeroPrefix,
RlpInvalidIndirection,
} }
impl StdError for DecoderError { impl StdError for DecoderError {

View File

@ -269,6 +269,7 @@ impl<'a> BasicDecoder<'a> {
Some(l @ 0xb8...0xbf) => { Some(l @ 0xb8...0xbf) => {
let len_of_len = l as usize - 0xb7; let len_of_len = l as usize - 0xb7;
let header_len = 1 + len_of_len; 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])); let value_len = try!(usize::from_bytes(&bytes[1..header_len]));
PayloadInfo::new(header_len, value_len) PayloadInfo::new(header_len, value_len)
} }
@ -277,6 +278,7 @@ impl<'a> BasicDecoder<'a> {
let len_of_len = l as usize - 0xf7; let len_of_len = l as usize - 0xf7;
let header_len = 1 + len_of_len; let header_len = 1 + len_of_len;
let value_len = try!(usize::from_bytes(&bytes[1..header_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) PayloadInfo::new(header_len, value_len)
}, },
// we cant reach this place, but rust requires _ to be implemented // we cant reach this place, but rust requires _ to be implemented
@ -302,7 +304,13 @@ impl<'a> Decoder for BasicDecoder<'a> {
// single byt value // single byt value
Some(l @ 0...0x7f) => Ok(try!(f(&[l]))), Some(l @ 0...0x7f) => Ok(try!(f(&[l]))),
// 0-55 bytes // 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 // longer than 55 bytes
Some(l @ 0xb8...0xbf) => { Some(l @ 0xb8...0xbf) => {
let len_of_len = l as usize - 0xb7; let len_of_len = l as usize - 0xb7;