sweep most unwraps from ethcore crate, dapps crate (#2762)
* sweep most unwraps from ethcore crate * purge unwrap from dapps server * whitespace [ci:none]
This commit is contained in:
parent
866ab9c7a3
commit
96f4c10453
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -335,6 +335,7 @@ dependencies = [
|
|||||||
"jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
"jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
||||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)",
|
"parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)",
|
||||||
"parity-dapps-glue 1.4.0",
|
"parity-dapps-glue 1.4.0",
|
||||||
|
@ -29,6 +29,7 @@ ethcore-util = { path = "../util" }
|
|||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-ui = { path = "./ui" }
|
||||||
parity-dapps-glue = { path = "./js-glue" }
|
parity-dapps-glue = { path = "./js-glue" }
|
||||||
|
mime = "0.2"
|
||||||
### DEPRECATED
|
### DEPRECATED
|
||||||
parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
|
parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
|
||||||
parity-dapps-home = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
|
parity-dapps-home = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
|
||||||
|
@ -27,6 +27,7 @@ use std::default::Default;
|
|||||||
pub struct File {
|
pub struct File {
|
||||||
pub path: &'static str,
|
pub path: &'static str,
|
||||||
pub content: &'static [u8],
|
pub content: &'static [u8],
|
||||||
|
// TODO: use strongly-typed MIME.
|
||||||
pub content_type: &'static str,
|
pub content_type: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +19,16 @@ use serde_json;
|
|||||||
use endpoint::Handler;
|
use endpoint::Handler;
|
||||||
use handlers::{ContentHandler, EchoHandler};
|
use handlers::{ContentHandler, EchoHandler};
|
||||||
|
|
||||||
pub fn as_json<T : Serialize>(val: &T) -> Box<Handler> {
|
pub fn as_json<T: Serialize>(val: &T) -> Box<Handler> {
|
||||||
Box::new(ContentHandler::ok(serde_json::to_string(val).unwrap(), "application/json".to_owned()))
|
let json = serde_json::to_string(val)
|
||||||
|
.expect("serialization to string is infallible; qed");
|
||||||
|
Box::new(ContentHandler::ok(json, mime!(Application/Json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_json_error<T : Serialize>(val: &T) -> Box<Handler> {
|
pub fn as_json_error<T: Serialize>(val: &T) -> Box<Handler> {
|
||||||
Box::new(ContentHandler::not_found(serde_json::to_string(val).unwrap(), "application/json".to_owned()))
|
let json = serde_json::to_string(val)
|
||||||
|
.expect("serialization to string is infallible; qed");
|
||||||
|
Box::new(ContentHandler::not_found(json, mime!(Application/Json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ping_response(local_domain: &str) -> Box<Handler> {
|
pub fn ping_response(local_domain: &str) -> Box<Handler> {
|
||||||
|
@ -54,8 +54,10 @@ impl ContentCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut removed = Vec::with_capacity(len - expected_size);
|
let mut removed = Vec::with_capacity(len - expected_size);
|
||||||
while len > expected_size {
|
|
||||||
let entry = self.cache.pop_front().unwrap();
|
while self.cache.len() > expected_size {
|
||||||
|
let entry = self.cache.pop_front().expect("expected_size bounded at 0, len is greater; qed");
|
||||||
|
|
||||||
match entry.1 {
|
match entry.1 {
|
||||||
ContentStatus::Fetching(ref fetch) => {
|
ContentStatus::Fetching(ref fetch) => {
|
||||||
trace!(target: "dapps", "Aborting {} because of limit.", entry.0);
|
trace!(target: "dapps", "Aborting {} because of limit.", entry.0);
|
||||||
@ -73,7 +75,6 @@ impl ContentCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removed.push(entry);
|
removed.push(entry);
|
||||||
len -= 1;
|
|
||||||
}
|
}
|
||||||
removed
|
removed
|
||||||
}
|
}
|
||||||
|
@ -156,9 +156,9 @@ impl URLHintContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut it = vec.into_iter();
|
let mut it = vec.into_iter();
|
||||||
let account_slash_repo = it.next().unwrap();
|
let account_slash_repo = it.next().expect("element 0 of 3-len vector known to exist; qed");
|
||||||
let commit = it.next().unwrap();
|
let commit = it.next().expect("element 1 of 3-len vector known to exist; qed");
|
||||||
let owner = it.next().unwrap();
|
let owner = it.next().expect("element 2 of 3-len vector known to exist qed");
|
||||||
|
|
||||||
match (account_slash_repo, commit, owner) {
|
match (account_slash_repo, commit, owner) {
|
||||||
(Token::String(account_slash_repo), Token::FixedBytes(commit), Token::Address(owner)) => {
|
(Token::String(account_slash_repo), Token::FixedBytes(commit), Token::Address(owner)) => {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use hyper::{header, server, Decoder, Encoder, Next};
|
use hyper::{header, server, Decoder, Encoder, Next};
|
||||||
use hyper::net::HttpStream;
|
use hyper::net::HttpStream;
|
||||||
|
use hyper::mime::Mime;
|
||||||
use hyper::status::StatusCode;
|
use hyper::status::StatusCode;
|
||||||
|
|
||||||
use util::version;
|
use util::version;
|
||||||
@ -29,22 +30,22 @@ use handlers::add_security_headers;
|
|||||||
pub struct ContentHandler {
|
pub struct ContentHandler {
|
||||||
code: StatusCode,
|
code: StatusCode,
|
||||||
content: String,
|
content: String,
|
||||||
mimetype: String,
|
mimetype: Mime,
|
||||||
write_pos: usize,
|
write_pos: usize,
|
||||||
safe_to_embed_at_port: Option<u16>,
|
safe_to_embed_at_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentHandler {
|
impl ContentHandler {
|
||||||
pub fn ok(content: String, mimetype: String) -> Self {
|
pub fn ok(content: String, mimetype: Mime) -> Self {
|
||||||
Self::new(StatusCode::Ok, content, mimetype)
|
Self::new(StatusCode::Ok, content, mimetype)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_found(content: String, mimetype: String) -> Self {
|
pub fn not_found(content: String, mimetype: Mime) -> Self {
|
||||||
Self::new(StatusCode::NotFound, content, mimetype)
|
Self::new(StatusCode::NotFound, content, mimetype)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn html(code: StatusCode, content: String, embeddable_at: Option<u16>) -> Self {
|
pub fn html(code: StatusCode, content: String, embeddable_at: Option<u16>) -> Self {
|
||||||
Self::new_embeddable(code, content, "text/html".into(), embeddable_at)
|
Self::new_embeddable(code, content, mime!(Text/Html), embeddable_at)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>) -> Self {
|
pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>) -> Self {
|
||||||
@ -61,11 +62,11 @@ impl ContentHandler {
|
|||||||
), embeddable_at)
|
), embeddable_at)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(code: StatusCode, content: String, mimetype: String) -> Self {
|
pub fn new(code: StatusCode, content: String, mimetype: Mime) -> Self {
|
||||||
Self::new_embeddable(code, content, mimetype, None)
|
Self::new_embeddable(code, content, mimetype, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_embeddable(code: StatusCode, content: String, mimetype: String, embeddable_at: Option<u16>) -> Self {
|
pub fn new_embeddable(code: StatusCode, content: String, mimetype: Mime, embeddable_at: Option<u16>) -> Self {
|
||||||
ContentHandler {
|
ContentHandler {
|
||||||
code: code,
|
code: code,
|
||||||
content: content,
|
content: content,
|
||||||
@ -87,7 +88,7 @@ impl server::Handler<HttpStream> for ContentHandler {
|
|||||||
|
|
||||||
fn on_response(&mut self, res: &mut server::Response) -> Next {
|
fn on_response(&mut self, res: &mut server::Response) -> Next {
|
||||||
res.set_status(self.code);
|
res.set_status(self.code);
|
||||||
res.headers_mut().set(header::ContentType(self.mimetype.parse().unwrap()));
|
res.headers_mut().set(header::ContentType(self.mimetype.clone()));
|
||||||
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port.clone());
|
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port.clone());
|
||||||
Next::write()
|
Next::write()
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ impl server::Handler<HttpStream> for EchoHandler {
|
|||||||
|
|
||||||
// Don't even read the payload if origin is forbidden!
|
// Don't even read the payload if origin is forbidden!
|
||||||
if let Cors::Forbidden = self.cors {
|
if let Cors::Forbidden = self.cors {
|
||||||
self.handler = Some(ContentHandler::ok(String::new(), "text/plain".into()));
|
self.handler = Some(ContentHandler::ok(String::new(), mime!(Text/Plain)));
|
||||||
Next::write()
|
Next::write()
|
||||||
} else {
|
} else {
|
||||||
Next::read()
|
Next::read()
|
||||||
@ -92,7 +92,7 @@ impl server::Handler<HttpStream> for EchoHandler {
|
|||||||
fn on_request_readable(&mut self, decoder: &mut Decoder<HttpStream>) -> Next {
|
fn on_request_readable(&mut self, decoder: &mut Decoder<HttpStream>) -> Next {
|
||||||
match decoder.read_to_string(&mut self.content) {
|
match decoder.read_to_string(&mut self.content) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
self.handler = Some(ContentHandler::ok(self.content.clone(), "application/json".into()));
|
self.handler = Some(ContentHandler::ok(self.content.clone(), mime!(Application/Json)));
|
||||||
Next::write()
|
Next::write()
|
||||||
},
|
},
|
||||||
Ok(_) => Next::read(),
|
Ok(_) => Next::read(),
|
||||||
@ -114,11 +114,15 @@ impl server::Handler<HttpStream> for EchoHandler {
|
|||||||
]));
|
]));
|
||||||
headers.set(header::AccessControlAllowOrigin::Value(domain.clone()));
|
headers.set(header::AccessControlAllowOrigin::Value(domain.clone()));
|
||||||
}
|
}
|
||||||
self.handler.as_mut().unwrap().on_response(res)
|
self.handler.as_mut()
|
||||||
|
.expect("handler always set in on_request, which is before now; qed")
|
||||||
|
.on_response(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
|
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
|
||||||
self.handler.as_mut().unwrap().on_response_writable(encoder)
|
self.handler.as_mut()
|
||||||
|
.expect("handler always set in on_request, which is before now; qed")
|
||||||
|
.on_response_writable(encoder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,10 +43,8 @@
|
|||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![cfg_attr(feature="nightly", plugin(clippy))]
|
#![cfg_attr(feature="nightly", plugin(clippy))]
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
|
||||||
extern crate url as url_lib;
|
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
extern crate url as url_lib;
|
||||||
extern crate unicase;
|
extern crate unicase;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
@ -61,6 +59,13 @@ extern crate ethcore_rpc;
|
|||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate linked_hash_map;
|
extern crate linked_hash_map;
|
||||||
extern crate fetch;
|
extern crate fetch;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate mime;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate ethcore_devtools as devtools;
|
extern crate ethcore_devtools as devtools;
|
||||||
|
|
||||||
|
@ -128,7 +128,12 @@ impl<T: Dapp> server::Handler<HttpStream> for PageHandler<T> {
|
|||||||
match self.file {
|
match self.file {
|
||||||
ServedFile::File(ref f) => {
|
ServedFile::File(ref f) => {
|
||||||
res.set_status(StatusCode::Ok);
|
res.set_status(StatusCode::Ok);
|
||||||
res.headers_mut().set(header::ContentType(f.content_type().parse().unwrap()));
|
|
||||||
|
match f.content_type().parse() {
|
||||||
|
Ok(mime) => res.headers_mut().set(header::ContentType(mime)),
|
||||||
|
Err(()) => debug!(target: "page_handler", "invalid MIME type: {}", f.content_type()),
|
||||||
|
}
|
||||||
|
|
||||||
// Security headers:
|
// Security headers:
|
||||||
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port);
|
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port);
|
||||||
Next::write()
|
Next::write()
|
||||||
|
@ -42,7 +42,7 @@ function FindProxyForURL(url, host) {{
|
|||||||
}}
|
}}
|
||||||
"#,
|
"#,
|
||||||
DAPPS_DOMAIN, path.host, path.port);
|
DAPPS_DOMAIN, path.host, path.port);
|
||||||
Box::new(ContentHandler::ok(content, "application/javascript".to_owned()))
|
Box::new(ContentHandler::ok(content, mime!(Application/Javascript)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,11 +81,15 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
|||||||
self.handler = match endpoint {
|
self.handler = match endpoint {
|
||||||
// First check special endpoints
|
// First check special endpoints
|
||||||
(ref path, ref endpoint) if self.special.contains_key(endpoint) => {
|
(ref path, ref endpoint) if self.special.contains_key(endpoint) => {
|
||||||
self.special.get(endpoint).unwrap().to_async_handler(path.clone().unwrap_or_default(), control)
|
self.special.get(endpoint)
|
||||||
|
.expect("special known to contain key; qed")
|
||||||
|
.to_async_handler(path.clone().unwrap_or_default(), control)
|
||||||
},
|
},
|
||||||
// Then delegate to dapp
|
// Then delegate to dapp
|
||||||
(Some(ref path), _) if self.endpoints.contains_key(&path.app_id) => {
|
(Some(ref path), _) if self.endpoints.contains_key(&path.app_id) => {
|
||||||
self.endpoints.get(&path.app_id).unwrap().to_async_handler(path.clone(), control)
|
self.endpoints.get(&path.app_id)
|
||||||
|
.expect("special known to contain key; qed")
|
||||||
|
.to_async_handler(path.clone(), control)
|
||||||
},
|
},
|
||||||
// Try to resolve and fetch the dapp
|
// Try to resolve and fetch the dapp
|
||||||
(Some(ref path), _) if self.fetch.contains(&path.app_id) => {
|
(Some(ref path), _) if self.fetch.contains(&path.app_id) => {
|
||||||
@ -108,7 +112,9 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
|||||||
},
|
},
|
||||||
// RPC by default
|
// RPC by default
|
||||||
_ => {
|
_ => {
|
||||||
self.special.get(&SpecialEndpoint::Rpc).unwrap().to_async_handler(EndpointPath::default(), control)
|
self.special.get(&SpecialEndpoint::Rpc)
|
||||||
|
.expect("RPC endpoint always stored; qed")
|
||||||
|
.to_async_handler(EndpointPath::default(), control)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,7 +149,9 @@ impl<A: Authorization> Router<A> {
|
|||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<String>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
||||||
let handler = special.get(&SpecialEndpoint::Utils).unwrap().to_handler(EndpointPath::default());
|
let handler = special.get(&SpecialEndpoint::Utils)
|
||||||
|
.expect("Utils endpoint always stored; qed")
|
||||||
|
.to_handler(EndpointPath::default());
|
||||||
Router {
|
Router {
|
||||||
control: Some(control),
|
control: Some(control),
|
||||||
main_page: main_page,
|
main_page: main_page,
|
||||||
|
@ -176,7 +176,8 @@ impl AccountProvider {
|
|||||||
AccountProvider {
|
AccountProvider {
|
||||||
unlocked: Mutex::new(HashMap::new()),
|
unlocked: Mutex::new(HashMap::new()),
|
||||||
address_book: Mutex::new(AddressBook::new(Default::default())),
|
address_book: Mutex::new(AddressBook::new(Default::default())),
|
||||||
sstore: Box::new(EthStore::open(Box::new(NullDir::default())).unwrap())
|
sstore: Box::new(EthStore::open(Box::new(NullDir::default()))
|
||||||
|
.expect("NullDir load always succeeds; qed"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ impl AccountProvider {
|
|||||||
|
|
||||||
/// Creates new random account and returns address and public key
|
/// Creates new random account and returns address and public key
|
||||||
pub fn new_account_and_public(&self, password: &str) -> Result<(Address, Public), Error> {
|
pub fn new_account_and_public(&self, password: &str) -> Result<(Address, Public), Error> {
|
||||||
let acc = Random.generate().unwrap();
|
let acc = Random.generate().expect("secp context has generation capabilities; qed");
|
||||||
let public = acc.public().clone();
|
let public = acc.public().clone();
|
||||||
let secret = acc.secret().clone();
|
let secret = acc.secret().clone();
|
||||||
let address = try!(self.sstore.insert_account(secret, password));
|
let address = try!(self.sstore.insert_account(secret, password));
|
||||||
|
@ -350,7 +350,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
let t = outcome.trace;
|
let t = outcome.trace;
|
||||||
self.block.traces.as_mut().map(|traces| traces.push(t));
|
self.block.traces.as_mut().map(|traces| traces.push(t));
|
||||||
self.block.receipts.push(outcome.receipt);
|
self.block.receipts.push(outcome.receipt);
|
||||||
Ok(self.block.receipts.last().unwrap())
|
Ok(self.block.receipts.last().expect("receipt just pushed; qed"))
|
||||||
}
|
}
|
||||||
Err(x) => Err(From::from(x))
|
Err(x) => Err(From::from(x))
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,8 @@ pub trait BlockProvider {
|
|||||||
|
|
||||||
/// Returns the header of the genesis block.
|
/// Returns the header of the genesis block.
|
||||||
fn genesis_header(&self) -> Header {
|
fn genesis_header(&self) -> Header {
|
||||||
self.block_header(&self.genesis_hash()).unwrap()
|
self.block_header(&self.genesis_hash())
|
||||||
|
.expect("Genesis header always stored; qed")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns numbers of blocks containing given bloom.
|
/// Returns numbers of blocks containing given bloom.
|
||||||
|
@ -55,18 +55,23 @@ impl<T> CacheManager<T> where T: Eq + Hash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..COLLECTION_QUEUE_SIZE {
|
for _ in 0..COLLECTION_QUEUE_SIZE {
|
||||||
let current_size = notify_unused(self.cache_usage.pop_back().unwrap());
|
if let Some(back) = self.cache_usage.pop_back() {
|
||||||
|
let current_size = notify_unused(back);
|
||||||
self.cache_usage.push_front(Default::default());
|
self.cache_usage.push_front(Default::default());
|
||||||
if current_size < self.max_cache_size {
|
if current_size < self.max_cache_size {
|
||||||
break;
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rotate_cache_if_needed(&mut self) {
|
fn rotate_cache_if_needed(&mut self) {
|
||||||
|
if self.cache_usage.len() == 0 { return }
|
||||||
|
|
||||||
if self.cache_usage[0].len() * self.bytes_per_cache_entry > self.pref_cache_size / COLLECTION_QUEUE_SIZE {
|
if self.cache_usage[0].len() * self.bytes_per_cache_entry > self.pref_cache_size / COLLECTION_QUEUE_SIZE {
|
||||||
let cache = self.cache_usage.pop_back().unwrap();
|
if let Some(cache) = self.cache_usage.pop_back() {
|
||||||
self.cache_usage.push_front(cache);
|
self.cache_usage.push_front(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,11 @@ impl Client {
|
|||||||
|
|
||||||
if number >= self.history {
|
if number >= self.history {
|
||||||
let n = number - self.history;
|
let n = number - self.history;
|
||||||
state.mark_canonical(&mut batch, n, &chain.block_hash(n).unwrap()).expect("DB commit failed");
|
if let Some(ancient_hash) = chain.block_hash(n) {
|
||||||
|
state.mark_canonical(&mut batch, n, &ancient_hash).expect("DB commit failed");
|
||||||
|
} else {
|
||||||
|
debug!(target: "client", "Missing expected hash for block {}", n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let route = chain.insert_block(&mut batch, block_data, receipts);
|
let route = chain.insert_block(&mut batch, block_data, receipts);
|
||||||
|
@ -123,10 +123,14 @@ pub trait Engine : Sync + Send {
|
|||||||
fn is_builtin(&self, a: &Address) -> bool { self.builtins().contains_key(a) }
|
fn is_builtin(&self, a: &Address) -> bool { self.builtins().contains_key(a) }
|
||||||
/// Determine the code execution cost of the builtin contract with address `a`.
|
/// Determine the code execution cost of the builtin contract with address `a`.
|
||||||
/// Panics if `is_builtin(a)` is not true.
|
/// Panics if `is_builtin(a)` is not true.
|
||||||
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 { self.builtins().get(a).unwrap().cost(input.len()) }
|
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 {
|
||||||
|
self.builtins().get(a).expect("queried cost of nonexistent builtin").cost(input.len())
|
||||||
|
}
|
||||||
/// Execution the builtin contract `a` on `input` and return `output`.
|
/// Execution the builtin contract `a` on `input` and return `output`.
|
||||||
/// Panics if `is_builtin(a)` is not true.
|
/// Panics if `is_builtin(a)` is not true.
|
||||||
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut BytesRef) { self.builtins().get(a).unwrap().execute(input, output); }
|
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut BytesRef) {
|
||||||
|
self.builtins().get(a).expect("attempted to execute nonexistent builtin").execute(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: sealing stuff - though might want to leave this for later.
|
// TODO: sealing stuff - though might want to leave this for later.
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
|
|||||||
|
|
||||||
let mut informant = informant::EvmInformant::new(ext.depth());
|
let mut informant = informant::EvmInformant::new(ext.depth());
|
||||||
|
|
||||||
let code = ¶ms.code.as_ref().unwrap();
|
let code = ¶ms.code.as_ref().expect("exec always called with code; qed");
|
||||||
let valid_jump_destinations = self.cache.jump_destinations(¶ms.code_hash, code);
|
let valid_jump_destinations = self.cache.jump_destinations(¶ms.code_hash, code);
|
||||||
|
|
||||||
let mut gasometer = Gasometer::<Cost>::new(try!(Cost::from_u256(params.gas)));
|
let mut gasometer = Gasometer::<Cost>::new(try!(Cost::from_u256(params.gas)));
|
||||||
@ -318,11 +318,11 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
// Get sender & receive addresses, check if we have balance
|
// Get sender & receive addresses, check if we have balance
|
||||||
let (sender_address, receive_address, has_balance, call_type) = match instruction {
|
let (sender_address, receive_address, has_balance, call_type) = match instruction {
|
||||||
instructions::CALL => {
|
instructions::CALL => {
|
||||||
let has_balance = ext.balance(¶ms.address) >= value.unwrap();
|
let has_balance = ext.balance(¶ms.address) >= value.expect("value set for all but delegate call; qed");
|
||||||
(¶ms.address, &code_address, has_balance, CallType::Call)
|
(¶ms.address, &code_address, has_balance, CallType::Call)
|
||||||
},
|
},
|
||||||
instructions::CALLCODE => {
|
instructions::CALLCODE => {
|
||||||
let has_balance = ext.balance(¶ms.address) >= value.unwrap();
|
let has_balance = ext.balance(¶ms.address) >= value.expect("value set for all but delegate call; qed");
|
||||||
(¶ms.address, ¶ms.address, has_balance, CallType::CallCode)
|
(¶ms.address, ¶ms.address, has_balance, CallType::CallCode)
|
||||||
},
|
},
|
||||||
instructions::DELEGATECALL => (¶ms.sender, ¶ms.address, true, CallType::DelegateCall),
|
instructions::DELEGATECALL => (¶ms.sender, ¶ms.address, true, CallType::DelegateCall),
|
||||||
|
@ -359,7 +359,7 @@ impl evm::Evm for JitEvm {
|
|||||||
data.timestamp = ext.env_info().timestamp as i64;
|
data.timestamp = ext.env_info().timestamp as i64;
|
||||||
|
|
||||||
self.context = Some(unsafe { evmjit::ContextHandle::new(data, schedule, &mut ext_handle) });
|
self.context = Some(unsafe { evmjit::ContextHandle::new(data, schedule, &mut ext_handle) });
|
||||||
let mut context = self.context.as_mut().unwrap();
|
let mut context = self.context.as_mut().expect("context handle set on the prior line; qed");
|
||||||
let res = context.exec();
|
let res = context.exec();
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
|
@ -427,8 +427,16 @@ impl<'a> Executive<'a> {
|
|||||||
trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n",
|
trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n",
|
||||||
t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value);
|
t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value);
|
||||||
|
|
||||||
trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, t.sender().unwrap());
|
let sender = match t.sender() {
|
||||||
self.state.add_balance(&t.sender().unwrap(), &refund_value);
|
Ok(sender) => sender,
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "executive", "attempted to finalize transaction without sender: {}", e);
|
||||||
|
return Err(ExecutionError::Internal);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, sender);
|
||||||
|
self.state.add_balance(&sender, &refund_value);
|
||||||
trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author);
|
trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author);
|
||||||
self.state.add_balance(&self.info.author, &fees_value);
|
self.state.add_balance(&self.info.author, &fees_value);
|
||||||
|
|
||||||
|
@ -199,8 +199,9 @@ impl Header {
|
|||||||
match &mut *hash {
|
match &mut *hash {
|
||||||
&mut Some(ref h) => h.clone(),
|
&mut Some(ref h) => h.clone(),
|
||||||
hash @ &mut None => {
|
hash @ &mut None => {
|
||||||
*hash = Some(self.rlp_sha3(Seal::With));
|
let h = self.rlp_sha3(Seal::With);
|
||||||
hash.as_ref().unwrap().clone()
|
*hash = Some(h.clone());
|
||||||
|
h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,8 +212,9 @@ impl Header {
|
|||||||
match &mut *hash {
|
match &mut *hash {
|
||||||
&mut Some(ref h) => h.clone(),
|
&mut Some(ref h) => h.clone(),
|
||||||
hash @ &mut None => {
|
hash @ &mut None => {
|
||||||
*hash = Some(self.rlp_sha3(Seal::Without));
|
let h = self.rlp_sha3(Seal::Without);
|
||||||
hash.as_ref().unwrap().clone()
|
*hash = Some(h.clone());
|
||||||
|
h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ impl GasPriceCalibrator {
|
|||||||
let gas_per_tx: f32 = 21000.0;
|
let gas_per_tx: f32 = 21000.0;
|
||||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||||
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||||
set_price(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap());
|
set_price(U256::from(wei_per_gas as u64));
|
||||||
}) {
|
}) {
|
||||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||||
} else {
|
} else {
|
||||||
@ -747,7 +747,7 @@ impl MinerService for Miner {
|
|||||||
let mut transaction_queue = self.transaction_queue.lock();
|
let mut transaction_queue = self.transaction_queue.lock();
|
||||||
let import = self.add_transactions_to_queue(
|
let import = self.add_transactions_to_queue(
|
||||||
chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue
|
chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue
|
||||||
).pop().unwrap();
|
).pop().expect("one result returned per added transaction; one added => one result; qed");
|
||||||
|
|
||||||
match import {
|
match import {
|
||||||
Ok(ref res) => {
|
Ok(ref res) => {
|
||||||
@ -869,7 +869,11 @@ impl MinerService for Miner {
|
|||||||
gas_used: receipt.gas_used - prev_gas,
|
gas_used: receipt.gas_used - prev_gas,
|
||||||
contract_address: match tx.action {
|
contract_address: match tx.action {
|
||||||
Action::Call(_) => None,
|
Action::Call(_) => None,
|
||||||
Action::Create => Some(contract_address(&tx.sender().unwrap(), &tx.nonce)),
|
Action::Create => {
|
||||||
|
let sender = tx.sender()
|
||||||
|
.expect("transactions in pending block have already been checked for valid sender; qed");
|
||||||
|
Some(contract_address(&sender, &tx.nonce))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
logs: receipt.logs.clone(),
|
logs: receipt.logs.clone(),
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,8 @@ impl<F: Fn(PriceInfo) + Sync + Send + 'static> Handler<HttpStream> for SetPriceH
|
|||||||
.and_then(|json| json.find_path(&["result", "ethusd"])
|
.and_then(|json| json.find_path(&["result", "ethusd"])
|
||||||
.and_then(|obj| match *obj {
|
.and_then(|obj| match *obj {
|
||||||
Json::String(ref s) => Some((self.set_price)(PriceInfo {
|
Json::String(ref s) => Some((self.set_price)(PriceInfo {
|
||||||
ethusd: FromStr::from_str(s).unwrap()
|
ethusd: FromStr::from_str(s)
|
||||||
|
.expect("Etherscan API will always return properly formatted price; qed")
|
||||||
})),
|
})),
|
||||||
_ => None,
|
_ => None,
|
||||||
}));
|
}));
|
||||||
@ -67,7 +68,11 @@ impl PriceInfo {
|
|||||||
let client = try!(Client::new().map_err(|_| ()));
|
let client = try!(Client::new().map_err(|_| ()));
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let _ = client.request(FromStr::from_str("http://api.etherscan.io/api?module=stats&action=ethprice").unwrap(), SetPriceHandler {
|
let url = FromStr::from_str("http://api.etherscan.io/api?module=stats&action=ethprice")
|
||||||
|
.expect("string known to be a valid URL; qed");
|
||||||
|
let _ = client.request(
|
||||||
|
url,
|
||||||
|
SetPriceHandler {
|
||||||
set_price: set_price,
|
set_price: set_price,
|
||||||
channel: tx,
|
channel: tx,
|
||||||
}).ok().and_then(|_| rx.recv().ok());
|
}).ok().and_then(|_| rx.recv().ok());
|
||||||
|
@ -700,7 +700,7 @@ impl TransactionQueue {
|
|||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
for k in nonces_from_sender {
|
for k in nonces_from_sender {
|
||||||
let order = self.current.drop(&sender, &k).unwrap();
|
let order = self.current.drop(&sender, &k).expect("transaction known to be in self.current; qed");
|
||||||
self.current.insert(sender, k, order.penalize());
|
self.current.insert(sender, k, order.penalize());
|
||||||
}
|
}
|
||||||
// Same thing for future
|
// Same thing for future
|
||||||
@ -709,7 +709,7 @@ impl TransactionQueue {
|
|||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
for k in nonces_from_sender {
|
for k in nonces_from_sender {
|
||||||
let order = self.future.drop(&sender, &k).unwrap();
|
let order = self.future.drop(&sender, &k).expect("transaction known to be in self.future; qed");
|
||||||
self.future.insert(sender, k, order.penalize());
|
self.future.insert(sender, k, order.penalize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,8 @@ impl Spec {
|
|||||||
if self.state_root_memo.read().is_none() {
|
if self.state_root_memo.read().is_none() {
|
||||||
*self.state_root_memo.write() = Some(self.genesis_state.root());
|
*self.state_root_memo.write() = Some(self.genesis_state.root());
|
||||||
}
|
}
|
||||||
self.state_root_memo.read().as_ref().unwrap().clone()
|
self.state_root_memo.read().as_ref().cloned()
|
||||||
|
.expect("state root memo ensured to be set at this point; qed")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the known knodes of the network in enode format.
|
/// Get the known knodes of the network in enode format.
|
||||||
|
@ -520,7 +520,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut trie = factories.trie.from_existing(db.as_hashdb_mut(), root).unwrap();
|
let mut trie = try!(factories.trie.from_existing(db.as_hashdb_mut(), root));
|
||||||
for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) {
|
for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) {
|
||||||
a.state = AccountState::Committed;
|
a.state = AccountState::Committed;
|
||||||
match a.account {
|
match a.account {
|
||||||
@ -691,14 +691,15 @@ impl State {
|
|||||||
}
|
}
|
||||||
self.note_cache(a);
|
self.note_cache(a);
|
||||||
|
|
||||||
match &mut self.cache.borrow_mut().get_mut(a).unwrap().account {
|
// at this point the entry is guaranteed to be in the cache.
|
||||||
|
RefMut::map(self.cache.borrow_mut(), |c| {
|
||||||
|
let mut entry = c.get_mut(a).expect("entry known to exist in the cache; qed");
|
||||||
|
|
||||||
|
match &mut entry.account {
|
||||||
&mut Some(ref mut acc) => not_default(acc),
|
&mut Some(ref mut acc) => not_default(acc),
|
||||||
slot => *slot = Some(default()),
|
slot => *slot = Some(default()),
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point the account is guaranteed to be in the cache.
|
|
||||||
RefMut::map(self.cache.borrow_mut(), |c| {
|
|
||||||
let mut entry = c.get_mut(a).unwrap();
|
|
||||||
// set the dirty flag after changing account data.
|
// set the dirty flag after changing account data.
|
||||||
entry.state = AccountState::Dirty;
|
entry.state = AccountState::Dirty;
|
||||||
match entry.account {
|
match entry.account {
|
||||||
|
@ -134,10 +134,11 @@ impl StateDB {
|
|||||||
let hash_count_entry = db.get(COL_ACCOUNT_BLOOM, ACCOUNT_BLOOM_HASHCOUNT_KEY)
|
let hash_count_entry = db.get(COL_ACCOUNT_BLOOM, ACCOUNT_BLOOM_HASHCOUNT_KEY)
|
||||||
.expect("Low-level database error");
|
.expect("Low-level database error");
|
||||||
|
|
||||||
if hash_count_entry.is_none() {
|
let hash_count_bytes = match hash_count_entry {
|
||||||
return Bloom::new(ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET);
|
Some(bytes) => bytes,
|
||||||
}
|
None => return Bloom::new(ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET),
|
||||||
let hash_count_bytes = hash_count_entry.unwrap();
|
};
|
||||||
|
|
||||||
assert_eq!(hash_count_bytes.len(), 1);
|
assert_eq!(hash_count_bytes.len(), 1);
|
||||||
let hash_count = hash_count_bytes[0];
|
let hash_count = hash_count_bytes[0];
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
|||||||
pub fn new(config: Config, tracesdb: Arc<Database>, extras: Arc<T>) -> Self {
|
pub fn new(config: Config, tracesdb: Arc<Database>, extras: Arc<T>) -> Self {
|
||||||
let mut batch = DBTransaction::new(&tracesdb);
|
let mut batch = DBTransaction::new(&tracesdb);
|
||||||
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
||||||
tracesdb.write(batch).unwrap();
|
tracesdb.write(batch).expect("failed to update version");
|
||||||
|
|
||||||
TraceDB {
|
TraceDB {
|
||||||
traces: RwLock::new(HashMap::new()),
|
traces: RwLock::new(HashMap::new()),
|
||||||
|
@ -21,7 +21,7 @@ use std::cell::*;
|
|||||||
use rlp::*;
|
use rlp::*;
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
use util::{H256, Address, U256, Bytes, HeapSizeOf};
|
use util::{H256, Address, U256, Bytes, HeapSizeOf};
|
||||||
use ethkey::{Signature, sign, Secret, Public, recover, public_to_address, Error as EthkeyError};
|
use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError};
|
||||||
use error::*;
|
use error::*;
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
@ -143,7 +143,8 @@ impl Transaction {
|
|||||||
|
|
||||||
/// Signs the transaction as coming from `sender`.
|
/// Signs the transaction as coming from `sender`.
|
||||||
pub fn sign(self, secret: &Secret) -> SignedTransaction {
|
pub fn sign(self, secret: &Secret) -> SignedTransaction {
|
||||||
let sig = sign(secret, &self.hash()).unwrap();
|
let sig = ::ethkey::sign(secret, &self.hash())
|
||||||
|
.expect("data is valid and context has signing capabilities; qed");
|
||||||
self.with_signature(sig)
|
self.with_signature(sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,8 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
|
|||||||
match bc.block_details(&hash) {
|
match bc.block_details(&hash) {
|
||||||
Some(details) => {
|
Some(details) => {
|
||||||
excluded.insert(details.parent.clone());
|
excluded.insert(details.parent.clone());
|
||||||
let b = bc.block(&hash).unwrap();
|
let b = bc.block(&hash)
|
||||||
|
.expect("parent already known to be stored; qed");
|
||||||
excluded.extend(BlockView::new(&b).uncle_hashes());
|
excluded.extend(BlockView::new(&b).uncle_hashes());
|
||||||
hash = details.parent;
|
hash = details.parent;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user