Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 4650961

Browse files
committed
Merge pull request #40 from gavofyork/gav
Fix RLP on consensus.
2 parents 870dff9 + 4be539a commit 4650961

File tree

6 files changed

+106
-6
lines changed

6 files changed

+106
-6
lines changed

src/crypto.rs

+13
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ impl KeyPair {
120120

121121
pub mod ec {
122122
use hash::*;
123+
use uint::*;
124+
use standard::*;
123125
use crypto::*;
124126
use crypto::{self};
125127

@@ -136,6 +138,7 @@ pub mod ec {
136138
}
137139
/// Returns siganture of message hash.
138140
pub fn sign(secret: &Secret, message: &H256) -> Result<Signature, CryptoError> {
141+
// TODO: allow creation of only low-s signatures.
139142
use secp256k1::*;
140143
let context = Secp256k1::new();
141144
let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) };
@@ -165,6 +168,16 @@ pub mod ec {
165168
}
166169
}
167170

171+
/// Check if this is a "low" signature.
172+
pub fn is_low(sig: &Signature) -> bool {
173+
H256::from_slice(&sig[32..64]) <= h256_from_hex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0")
174+
}
175+
176+
/// Check if this is a "low" signature.
177+
pub fn is_low_s(s: &U256) -> bool {
178+
s <= &U256::from_str("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0").unwrap()
179+
}
180+
168181
/// Check if each component of the signature is in range.
169182
pub fn is_valid(sig: &Signature) -> bool {
170183
sig[64] <= 1 &&

src/hash.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -224,16 +224,22 @@ macro_rules! impl_hash {
224224
}
225225
}
226226

227-
impl PartialOrd for $from {
228-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
227+
impl Ord for $from {
228+
fn cmp(&self, other: &Self) -> Ordering {
229229
for i in 0..$size {
230230
if self.0[i] > other.0[i] {
231-
return Some(Ordering::Greater);
231+
return Ordering::Greater;
232232
} else if self.0[i] < other.0[i] {
233-
return Some(Ordering::Less);
233+
return Ordering::Less;
234234
}
235235
}
236-
Some(Ordering::Equal)
236+
Ordering::Equal
237+
}
238+
}
239+
240+
impl PartialOrd for $from {
241+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
242+
Some(self.cmp(other))
237243
}
238244
}
239245

src/json_aid.rs

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use common::*;
2+
3+
pub fn clean(s: &str) -> &str {
4+
if s.len() >= 2 && &s[0..2] == "0x" {
5+
&s[2..]
6+
} else {
7+
s
8+
}
9+
}
10+
11+
pub fn bytes_from_json(json: &Json) -> Bytes {
12+
let s = json.as_string().unwrap_or("");
13+
if s.len() % 2 == 1 {
14+
FromHex::from_hex(&("0".to_string() + &(clean(s).to_string()))[..]).unwrap_or(vec![])
15+
} else {
16+
FromHex::from_hex(clean(s)).unwrap_or(vec![])
17+
}
18+
}
19+
20+
pub fn address_from_json(json: &Json) -> Address {
21+
let s = json.as_string().unwrap_or("0000000000000000000000000000000000000000");
22+
if s.len() % 2 == 1 {
23+
address_from_hex(&("0".to_string() + &(clean(s).to_string()))[..])
24+
} else {
25+
address_from_hex(clean(s))
26+
}
27+
}
28+
29+
pub fn h256_from_json(json: &Json) -> H256 {
30+
let s = json.as_string().unwrap_or("0000000000000000000000000000000000000000000000000000000000000000");
31+
if s.len() % 2 == 1 {
32+
h256_from_hex(&("0".to_string() + &(clean(s).to_string()))[..])
33+
} else {
34+
h256_from_hex(clean(s))
35+
}
36+
}
37+
38+
pub fn u256_from_hex(s: &str) -> U256 {
39+
if s.len() >= 2 && &s[0..2] == "0x" {
40+
U256::from_str(&s[2..]).unwrap_or(U256::from(0))
41+
} else {
42+
U256::from_dec_str(s).unwrap_or(U256::from(0))
43+
}
44+
}
45+
46+
pub fn u256_from_json(json: &Json) -> U256 {
47+
u256_from_hex(json.as_string().unwrap_or(""))
48+
}
49+
50+
pub fn usize_from_json(json: &Json) -> usize {
51+
u256_from_json(json).low_u64() as usize
52+
}
53+
54+
pub fn u64_from_json(json: &Json) -> u64 {
55+
u256_from_json(json).low_u64()
56+
}
57+
58+
pub fn u32_from_json(json: &Json) -> u32 {
59+
u256_from_json(json).low_u32()
60+
}
61+
62+
pub fn u16_from_json(json: &Json) -> u16 {
63+
u256_from_json(json).low_u32() as u16
64+
}
65+
66+
pub fn u8_from_json(json: &Json) -> u8 {
67+
u256_from_json(json).low_u32() as u8
68+
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub mod hash;
5757
pub mod uint;
5858
pub mod bytes;
5959
pub mod rlp;
60+
pub mod json_aid;
6061
pub mod vector;
6162
pub mod sha3;
6263
pub mod hashdb;
@@ -74,6 +75,7 @@ pub mod semantic_version;
7475
pub mod network;
7576

7677
pub use common::*;
78+
pub use json_aid::*;
7779
pub use rlp::*;
7880
pub use hashdb::*;
7981
pub use memorydb::*;

src/rlp/rlperrors.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pub enum DecoderError {
99
RlpExpectedToBeList,
1010
RlpExpectedToBeData,
1111
RlpIncorrectListLen,
12+
RlpDataLenWithZeroPrefix,
13+
RlpListLenWithZeroPrefix,
14+
RlpInvalidIndirection,
1215
}
1316

1417
impl StdError for DecoderError {

src/rlp/untrusted_rlp.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ impl<'a> BasicDecoder<'a> {
269269
Some(l @ 0xb8...0xbf) => {
270270
let len_of_len = l as usize - 0xb7;
271271
let header_len = 1 + len_of_len;
272+
if bytes[1] == 0 { return Err(DecoderError::RlpDataLenWithZeroPrefix); }
272273
let value_len = try!(usize::from_bytes(&bytes[1..header_len]));
273274
PayloadInfo::new(header_len, value_len)
274275
}
@@ -277,6 +278,7 @@ impl<'a> BasicDecoder<'a> {
277278
let len_of_len = l as usize - 0xf7;
278279
let header_len = 1 + len_of_len;
279280
let value_len = try!(usize::from_bytes(&bytes[1..header_len]));
281+
if bytes[1] == 0 { return Err(DecoderError::RlpListLenWithZeroPrefix); }
280282
PayloadInfo::new(header_len, value_len)
281283
},
282284
// we cant reach this place, but rust requires _ to be implemented
@@ -302,7 +304,13 @@ impl<'a> Decoder for BasicDecoder<'a> {
302304
// single byt value
303305
Some(l @ 0...0x7f) => Ok(try!(f(&[l]))),
304306
// 0-55 bytes
305-
Some(l @ 0x80...0xb7) => Ok(try!(f(&bytes[1..(1 + l as usize - 0x80)]))),
307+
Some(l @ 0x80...0xb7) => {
308+
let d = &bytes[1..(1 + l as usize - 0x80)];
309+
if l == 0x81 && d[0] < 0x80 {
310+
return Err(DecoderError::RlpInvalidIndirection);
311+
}
312+
Ok(try!(f(d)))
313+
},
306314
// longer than 55 bytes
307315
Some(l @ 0xb8...0xbf) => {
308316
let len_of_len = l as usize - 0xb7;

0 commit comments

Comments
 (0)