Introduce to_hex() utility in bigint. Fix tests.

This commit is contained in:
Gav Wood 2016-11-29 13:46:06 +01:00
parent 0cf8db58b8
commit 436016ef02
No known key found for this signature in database
GPG Key ID: C49C1ACA1CC9B252
5 changed files with 48 additions and 23 deletions

View File

@ -495,7 +495,7 @@ fn rpc_eth_pending_transaction_by_hash() {
tester.miner.pending_transactions.lock().insert(H256::zero(), tx); tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
} }
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":0,"to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":27,"value":"0xa"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
let request = r#"{ let request = r#"{
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_getTransactionByHash", "method": "eth_getTransactionByHash",
@ -814,12 +814,12 @@ fn rpc_eth_sign_transaction() {
&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) + &format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
r#""nonce":"0x1","# + r#""nonce":"0x1","# +
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) + &format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
&format!("\"r\":\"0x{}\",", signature.r().to_hex()) + &format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
&format!("\"raw\":\"0x{}\",", rlp.to_hex()) + &format!("\"raw\":\"0x{}\",", rlp.to_hex()) +
&format!("\"s\":\"0x{}\",", signature.s().to_hex()) + &format!("\"s\":\"0x{}\",", U256::from(signature.s()).to_hex()) +
&format!("\"standardV\":{},", t.standard_v()) + &format!("\"standardV\":\"0x{}\",", U256::from(t.standard_v()).to_hex()) +
r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# + r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# +
&format!("\"v\":{},", t.original_v()) + &format!("\"v\":\"0x{}\",", U256::from(t.original_v()).to_hex()) +
r#""value":"0x9184e72a""# + r#""value":"0x9184e72a""# +
r#"}},"id":1}"#; r#"}},"id":1}"#;

View File

@ -282,12 +282,12 @@ fn should_add_sign_transaction_to_the_queue() {
&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) + &format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
r#""nonce":"0x1","# + r#""nonce":"0x1","# +
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) + &format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
&format!("\"r\":\"0x{}\",", signature.r().to_hex()) + &format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
&format!("\"raw\":\"0x{}\",", rlp.to_hex()) + &format!("\"raw\":\"0x{}\",", rlp.to_hex()) +
&format!("\"s\":\"0x{}\",", signature.s().to_hex()) + &format!("\"s\":\"0x{}\",", U256::from(signature.s()).to_hex()) +
&format!("\"standardV\":{},", t.standard_v()) + &format!("\"standardV\":\"0x{}\",", U256::from(t.standard_v()).to_hex()) +
r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# + r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# +
&format!("\"v\":{},", t.original_v()) + &format!("\"v\":\"0x{}\",", U256::from(t.original_v()).to_hex()) +
r#""value":"0x9184e72a""# + r#""value":"0x9184e72a""# +
r#"}},"id":1}"#; r#"}},"id":1}"#;

View File

@ -139,7 +139,7 @@ mod tests {
fn test_serialize_block_transactions() { fn test_serialize_block_transactions() {
let t = BlockTransactions::Full(vec![Transaction::default()]); let t = BlockTransactions::Full(vec![Transaction::default()]);
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":0,"v":0,"r":"0x0","s":"0x0"}]"#); assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0"}]"#);
let t = BlockTransactions::Hashes(vec![H256::default().into()]); let t = BlockTransactions::Hashes(vec![H256::default().into()]);
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();

View File

@ -62,9 +62,9 @@ pub struct Transaction {
pub network_id: Option<u8>, pub network_id: Option<u8>,
/// The standardised V field of the signature (0 or 1). /// The standardised V field of the signature (0 or 1).
#[serde(rename="standardV")] #[serde(rename="standardV")]
pub standard_v: u8, pub standard_v: U256,
/// The standardised V field of the signature. /// The standardised V field of the signature.
pub v: u8, pub v: U256,
/// The R field of the signature. /// The R field of the signature.
pub r: U256, pub r: U256,
/// The S field of the signature. /// The S field of the signature.
@ -183,8 +183,8 @@ impl From<LocalizedTransaction> for Transaction {
raw: ::rlp::encode(&t.signed).to_vec().into(), raw: ::rlp::encode(&t.signed).to_vec().into(),
public_key: t.public_key().ok().map(Into::into), public_key: t.public_key().ok().map(Into::into),
network_id: t.network_id(), network_id: t.network_id(),
standard_v: t.standard_v(), standard_v: t.standard_v().into(),
v: t.original_v(), v: t.original_v().into(),
r: signature.r().into(), r: signature.r().into(),
s: signature.s().into(), s: signature.s().into(),
} }
@ -216,8 +216,8 @@ impl From<SignedTransaction> for Transaction {
raw: ::rlp::encode(&t).to_vec().into(), raw: ::rlp::encode(&t).to_vec().into(),
public_key: t.public_key().ok().map(Into::into), public_key: t.public_key().ok().map(Into::into),
network_id: t.network_id(), network_id: t.network_id(),
standard_v: t.standard_v(), standard_v: t.standard_v().into(),
v: t.original_v(), v: t.original_v().into(),
r: signature.r().into(), r: signature.r().into(),
s: signature.s().into(), s: signature.s().into(),
} }
@ -248,7 +248,7 @@ mod tests {
fn test_transaction_serialize() { fn test_transaction_serialize() {
let t = Transaction::default(); let t = Transaction::default();
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":0,"v":0,"r":"0x0","s":"0x0"}"#); assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0"}"#);
} }
#[test] #[test]

View File

@ -37,12 +37,12 @@
//! implementations for even more speed, hidden behind the `x64_arithmetic` //! implementations for even more speed, hidden behind the `x64_arithmetic`
//! feature flag. //! feature flag.
use std::{mem, fmt}; use std::{mem, fmt, cmp};
use std::str::{FromStr}; use std::str::{FromStr};
use std::hash::Hash; use std::hash::Hash;
use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub}; use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
use std::cmp::Ordering; use std::cmp::Ordering;
use rustc_serialize::hex::{FromHex, FromHexError}; use rustc_serialize::hex::{ToHex, FromHex, FromHexError};
/// Conversion from decimal string error /// Conversion from decimal string error
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -520,8 +520,10 @@ pub trait Uint: Sized + Default + FromStr + From<u64> + fmt::Debug + fmt::Displa
fn bit(&self, index: usize) -> bool; fn bit(&self, index: usize) -> bool;
/// Return single byte /// Return single byte
fn byte(&self, index: usize) -> u8; fn byte(&self, index: usize) -> u8;
/// Convert U256 to the sequence of bytes with a big endian /// Convert to the sequence of bytes with a big endian
fn to_big_endian(&self, bytes: &mut[u8]); fn to_big_endian(&self, bytes: &mut[u8]);
/// Convert to a non-zero-prefixed hex representation prefixed by `0x`.
fn to_hex(&self) -> String;
/// Create `Uint(10**n)` /// Create `Uint(10**n)`
fn exp10(n: usize) -> Self; fn exp10(n: usize) -> Self;
/// Return eponentation `self**other`. Panic on overflow. /// Return eponentation `self**other`. Panic on overflow.
@ -684,6 +686,17 @@ macro_rules! construct_uint {
} }
} }
#[inline]
fn to_hex(&self) -> String {
if self.is_zero() { return "0".to_owned(); } // special case.
let mut bytes = [0u8; 8 * $n_words];
self.to_big_endian(&mut bytes);
let bp7 = self.bits() + 7;
let len = cmp::max(bp7 / 8, 1);
let bytes_hex = bytes[bytes.len() - len..].to_hex();
(&bytes_hex[1 - bp7 % 8 / 4..]).to_owned()
}
#[inline] #[inline]
fn exp10(n: usize) -> Self { fn exp10(n: usize) -> Self {
match n { match n {
@ -1637,7 +1650,7 @@ mod tests {
} }
#[test] #[test]
fn uint256_pow () { fn uint256_pow() {
assert_eq!(U256::from(10).pow(U256::from(0)), U256::from(1)); assert_eq!(U256::from(10).pow(U256::from(0)), U256::from(1));
assert_eq!(U256::from(10).pow(U256::from(1)), U256::from(10)); assert_eq!(U256::from(10).pow(U256::from(1)), U256::from(10));
assert_eq!(U256::from(10).pow(U256::from(2)), U256::from(100)); assert_eq!(U256::from(10).pow(U256::from(2)), U256::from(100));
@ -1647,12 +1660,24 @@ mod tests {
#[test] #[test]
#[should_panic] #[should_panic]
fn uint256_pow_overflow_panic () { fn uint256_pow_overflow_panic() {
U256::from(2).pow(U256::from(0x100)); U256::from(2).pow(U256::from(0x100));
} }
#[test] #[test]
fn uint256_overflowing_pow () { fn should_format_hex_correctly() {
assert_eq!(&U256::from(0).to_hex(), &"0");
assert_eq!(&U256::from(0x1).to_hex(), &"1");
assert_eq!(&U256::from(0xf).to_hex(), &"f");
assert_eq!(&U256::from(0x10).to_hex(), &"10");
assert_eq!(&U256::from(0xff).to_hex(), &"ff");
assert_eq!(&U256::from(0x100).to_hex(), &"100");
assert_eq!(&U256::from(0xfff).to_hex(), &"fff");
assert_eq!(&U256::from(0x1000).to_hex(), &"1000");
}
#[test]
fn uint256_overflowing_pow() {
// assert_eq!( // assert_eq!(
// U256::from(2).overflowing_pow(U256::from(0xff)), // U256::from(2).overflowing_pow(U256::from(0xff)),
// (U256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap(), false) // (U256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap(), false)