add some block tests
This commit is contained in:
parent
453579e347
commit
7c465c2027
|
@ -52,6 +52,15 @@ name = "base64"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -320,6 +329,7 @@ dependencies = [
|
||||||
name = "ethers-types"
|
name = "ethers-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethereum-types 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethers-utils 0.1.0",
|
"ethers-utils 0.1.0",
|
||||||
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1523,6 +1533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||||
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||||
|
"checksum bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
|
||||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
"checksum bitvec 0.17.4 (registry+https://github.com/rust-lang/crates.io-index)" = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c"
|
"checksum bitvec 0.17.4 (registry+https://github.com/rust-lang/crates.io-index)" = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c"
|
||||||
"checksum bumpalo 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6"
|
"checksum bumpalo 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6"
|
||||||
|
|
|
@ -21,3 +21,4 @@ zeroize = { version = "1.1.0", default-features = false }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = { version = "1.0.53", default-features = false }
|
serde_json = { version = "1.0.53", default-features = false }
|
||||||
rand = { version = "0.5.1" }
|
rand = { version = "0.5.1" }
|
||||||
|
bincode = "1.2.1"
|
||||||
|
|
|
@ -134,3 +134,21 @@ impl Serialize for BlockNumber {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::{Transaction, TxHash};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_blk_no_txs() {
|
||||||
|
let block = r#"{"number":"0x3","hash":"0xda53da08ef6a3cbde84c33e51c04f68c3853b6a3731f10baa2324968eee63972","parentHash":"0x689c70c080ca22bc0e681694fa803c1aba16a69c8b6368fed5311d279eb9de90","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x7270c1c4440180f2bd5215809ee3d545df042b67329499e1ab97eb759d31610d","stateRoot":"0x29f32984517a7d25607da485b23cefabfd443751422ca7e603395e1de9bc8a4b","receiptsRoot":"0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2","miner":"0x0000000000000000000000000000000000000000","difficulty":"0x0","totalDifficulty":"0x0","extraData":"0x","size":"0x3e8","gasLimit":"0x6691b7","gasUsed":"0x5208","timestamp":"0x5ecedbb9","transactions":["0xc3c5f700243de37ae986082fd2af88d2a7c2752a0c0f7b9d6ac47c729d45e067"],"uncles":[]}"#;
|
||||||
|
let _block: Block<TxHash> = serde_json::from_str(&block).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_blk_with_txs() {
|
||||||
|
let block = r#"{"number":"0x3","hash":"0xda53da08ef6a3cbde84c33e51c04f68c3853b6a3731f10baa2324968eee63972","parentHash":"0x689c70c080ca22bc0e681694fa803c1aba16a69c8b6368fed5311d279eb9de90","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x7270c1c4440180f2bd5215809ee3d545df042b67329499e1ab97eb759d31610d","stateRoot":"0x29f32984517a7d25607da485b23cefabfd443751422ca7e603395e1de9bc8a4b","receiptsRoot":"0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2","miner":"0x0000000000000000000000000000000000000000","difficulty":"0x0","totalDifficulty":"0x0","extraData":"0x","size":"0x3e8","gasLimit":"0x6691b7","gasUsed":"0x5208","timestamp":"0x5ecedbb9","transactions":[{"hash":"0xc3c5f700243de37ae986082fd2af88d2a7c2752a0c0f7b9d6ac47c729d45e067","nonce":"0x2","blockHash":"0xda53da08ef6a3cbde84c33e51c04f68c3853b6a3731f10baa2324968eee63972","blockNumber":"0x3","transactionIndex":"0x0","from":"0xfdcedc3bfca10ecb0890337fbdd1977aba84807a","to":"0xdca8ce283150ab773bcbeb8d38289bdb5661de1e","value":"0x0","gas":"0x15f90","gasPrice":"0x4a817c800","input":"0x","v":"0x25","r":"0x19f2694eb9113656dbea0b925e2e7ceb43df83e601c4116aee9c0dd99130be88","s":"0x73e5764b324a4f7679d890a198ba658ba1c8cd36983ff9797e10b1b89dbb448e"}],"uncles":[]}"#;
|
||||||
|
let _block: Block<Transaction> = serde_json::from_str(&block).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ use serde::{ser::Error as SerializationError, Deserialize, Deserializer, Seriali
|
||||||
/// ENS name or Ethereum Address. Not RLP encoded/serialized if it's a name
|
/// ENS name or Ethereum Address. Not RLP encoded/serialized if it's a name
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum NameOrAddress {
|
pub enum NameOrAddress {
|
||||||
|
/// An ENS Name (format does not get checked)
|
||||||
Name(String),
|
Name(String),
|
||||||
|
/// An Ethereum Address
|
||||||
Address(Address),
|
Address(Address),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +21,14 @@ impl Encodable for &NameOrAddress {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for NameOrAddress {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
if let NameOrAddress::Address(inner) = self {
|
||||||
|
inner.rlp_append(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&str> for NameOrAddress {
|
impl From<&str> for NameOrAddress {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
NameOrAddress::Name(s.to_owned())
|
NameOrAddress::Name(s.to_owned())
|
||||||
|
@ -58,3 +68,55 @@ impl<'de> Deserialize<'de> for NameOrAddress {
|
||||||
Ok(NameOrAddress::Address(inner))
|
Ok(NameOrAddress::Address(inner))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rlp_name_not_serialized() {
|
||||||
|
let name = NameOrAddress::Name("ens.eth".to_string());
|
||||||
|
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
name.rlp_append(&mut rlp);
|
||||||
|
assert!(rlp.is_empty());
|
||||||
|
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
(&name).rlp_append(&mut rlp);
|
||||||
|
assert!(rlp.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rlp_address_serialized() {
|
||||||
|
let addr = "f02c1c8e6114b1dbe8937a39260b5b0a374432bb".parse().unwrap();
|
||||||
|
let union = NameOrAddress::Address(addr);
|
||||||
|
|
||||||
|
let mut expected = RlpStream::new();
|
||||||
|
addr.rlp_append(&mut expected);
|
||||||
|
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
union.rlp_append(&mut rlp);
|
||||||
|
assert_eq!(rlp.as_raw(), expected.as_raw());
|
||||||
|
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
(&union).rlp_append(&mut rlp);
|
||||||
|
assert_eq!(rlp.as_raw(), expected.as_raw());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_name_not_serialized() {
|
||||||
|
let name = NameOrAddress::Name("ens.eth".to_string());
|
||||||
|
bincode::serialize(&name).unwrap_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_address_serialized() {
|
||||||
|
let addr = "f02c1c8e6114b1dbe8937a39260b5b0a374432bb".parse().unwrap();
|
||||||
|
let union = NameOrAddress::Address(addr);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
bincode::serialize(&addr).unwrap(),
|
||||||
|
bincode::serialize(&union).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use ethers_utils::{hash_message, keccak256};
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use secp256k1::{
|
use secp256k1::{
|
||||||
key::ONE_KEY, Error as SecpError, Message, PublicKey as PubKey, Secp256k1, SecretKey,
|
key::ONE_KEY, Error as SecpError, Message, PublicKey as PubKey, recovery::RecoveryId, Secp256k1,
|
||||||
|
SecretKey,
|
||||||
};
|
};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -119,14 +120,7 @@ impl PrivateKey {
|
||||||
.sign_recoverable(message, &self.0)
|
.sign_recoverable(message, &self.0)
|
||||||
.serialize_compact();
|
.serialize_compact();
|
||||||
|
|
||||||
let standard_v = recovery_id.to_i32() as u64;
|
let v = to_eip155_v(recovery_id, chain_id);
|
||||||
let v = if let Some(chain_id) = chain_id {
|
|
||||||
// When signing with a chain ID, add chain replay protection.
|
|
||||||
standard_v + 35 + chain_id.as_u64() * 2
|
|
||||||
} else {
|
|
||||||
// Otherwise, convert to 'Electrum' notation.
|
|
||||||
standard_v + 27
|
|
||||||
};
|
|
||||||
let r = H256::from_slice(&signature[..32]);
|
let r = H256::from_slice(&signature[..32]);
|
||||||
let s = H256::from_slice(&signature[32..]);
|
let s = H256::from_slice(&signature[32..]);
|
||||||
|
|
||||||
|
@ -135,6 +129,17 @@ impl PrivateKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_eip155_v(recovery_id: RecoveryId, chain_id: Option<U64>) -> u64 {
|
||||||
|
let standard_v = recovery_id.to_i32() as u64;
|
||||||
|
if let Some(chain_id) = chain_id {
|
||||||
|
// When signing with a chain ID, add chain replay protection.
|
||||||
|
standard_v + 35 + chain_id.as_u64() * 2
|
||||||
|
} else {
|
||||||
|
// Otherwise, convert to 'Electrum' notation.
|
||||||
|
standard_v + 27
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for PrivateKey {
|
impl Default for PrivateKey {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
PrivateKey(ONE_KEY)
|
PrivateKey(ONE_KEY)
|
||||||
|
|
Loading…
Reference in New Issue