return default accounts from on_demand
This commit is contained in:
parent
73fa0cdc31
commit
1b0a369889
@ -35,7 +35,7 @@ use futures::sync::oneshot::{self, Sender, Receiver};
|
|||||||
use network::PeerId;
|
use network::PeerId;
|
||||||
use rlp::RlpStream;
|
use rlp::RlpStream;
|
||||||
use util::{Bytes, RwLock, Mutex, U256, H256};
|
use util::{Bytes, RwLock, Mutex, U256, H256};
|
||||||
use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY_LIST_RLP};
|
use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY, SHA3_EMPTY_LIST_RLP};
|
||||||
|
|
||||||
use net::{self, Handler, Status, Capabilities, Announcement, EventContext, BasicContext, ReqId};
|
use net::{self, Handler, Status, Capabilities, Announcement, EventContext, BasicContext, ReqId};
|
||||||
use cache::Cache;
|
use cache::Cache;
|
||||||
@ -83,7 +83,7 @@ enum Pending {
|
|||||||
HeaderByHash(request::HeaderByHash, Sender<encoded::Header>),
|
HeaderByHash(request::HeaderByHash, Sender<encoded::Header>),
|
||||||
Block(request::Body, Sender<encoded::Block>),
|
Block(request::Body, Sender<encoded::Block>),
|
||||||
BlockReceipts(request::BlockReceipts, Sender<Vec<Receipt>>),
|
BlockReceipts(request::BlockReceipts, Sender<Vec<Receipt>>),
|
||||||
Account(request::Account, Sender<Option<BasicAccount>>),
|
Account(request::Account, Sender<BasicAccount>),
|
||||||
Code(request::Code, Sender<Bytes>),
|
Code(request::Code, Sender<Bytes>),
|
||||||
TxProof(request::TransactionProof, Sender<Result<Executed, ExecutionError>>),
|
TxProof(request::TransactionProof, Sender<Result<Executed, ExecutionError>>),
|
||||||
}
|
}
|
||||||
@ -136,18 +136,20 @@ pub struct OnDemand {
|
|||||||
pending_requests: RwLock<HashMap<ReqId, Pending>>,
|
pending_requests: RwLock<HashMap<ReqId, Pending>>,
|
||||||
cache: Arc<Mutex<Cache>>,
|
cache: Arc<Mutex<Cache>>,
|
||||||
orphaned_requests: RwLock<Vec<Pending>>,
|
orphaned_requests: RwLock<Vec<Pending>>,
|
||||||
|
start_nonce: U256,
|
||||||
}
|
}
|
||||||
|
|
||||||
const RECEIVER_IN_SCOPE: &'static str = "Receiver is still in scope, so it's not dropped; qed";
|
const RECEIVER_IN_SCOPE: &'static str = "Receiver is still in scope, so it's not dropped; qed";
|
||||||
|
|
||||||
impl OnDemand {
|
impl OnDemand {
|
||||||
/// Create a new `OnDemand` service with the given cache.
|
/// Create a new `OnDemand` service with the given cache.
|
||||||
pub fn new(cache: Arc<Mutex<Cache>>) -> Self {
|
pub fn new(cache: Arc<Mutex<Cache>>, account_start_nonce: U256) -> Self {
|
||||||
OnDemand {
|
OnDemand {
|
||||||
peers: RwLock::new(HashMap::new()),
|
peers: RwLock::new(HashMap::new()),
|
||||||
pending_requests: RwLock::new(HashMap::new()),
|
pending_requests: RwLock::new(HashMap::new()),
|
||||||
cache: cache,
|
cache: cache,
|
||||||
orphaned_requests: RwLock::new(Vec::new()),
|
orphaned_requests: RwLock::new(Vec::new()),
|
||||||
|
start_nonce: account_start_nonce,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +270,7 @@ impl OnDemand {
|
|||||||
|
|
||||||
/// Request an account by address and block header -- which gives a hash to query and a state root
|
/// Request an account by address and block header -- which gives a hash to query and a state root
|
||||||
/// to verify against.
|
/// to verify against.
|
||||||
pub fn account(&self, ctx: &BasicContext, req: request::Account) -> Receiver<Option<BasicAccount>> {
|
pub fn account(&self, ctx: &BasicContext, req: request::Account) -> Receiver<BasicAccount> {
|
||||||
let (sender, receiver) = oneshot::channel();
|
let (sender, receiver) = oneshot::channel();
|
||||||
self.dispatch(ctx, Pending::Account(req, sender));
|
self.dispatch(ctx, Pending::Account(req, sender));
|
||||||
receiver
|
receiver
|
||||||
@ -279,7 +281,7 @@ impl OnDemand {
|
|||||||
let (sender, receiver) = oneshot::channel();
|
let (sender, receiver) = oneshot::channel();
|
||||||
|
|
||||||
// fast path for no code.
|
// fast path for no code.
|
||||||
if req.code_hash == ::util::sha3::SHA3_EMPTY {
|
if req.code_hash == SHA3_EMPTY {
|
||||||
sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE)
|
sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE)
|
||||||
} else {
|
} else {
|
||||||
self.dispatch(ctx, Pending::Code(req, sender));
|
self.dispatch(ctx, Pending::Code(req, sender));
|
||||||
@ -497,10 +499,19 @@ impl Handler for OnDemand {
|
|||||||
Pending::Account(req, sender) => {
|
Pending::Account(req, sender) => {
|
||||||
if let NetworkResponse::Account(ref response) = *response {
|
if let NetworkResponse::Account(ref response) = *response {
|
||||||
match req.check_response(&response.proof) {
|
match req.check_response(&response.proof) {
|
||||||
Ok(maybe_account) => {
|
Ok(account) => {
|
||||||
|
let account = account.unwrap_or_else(|| {
|
||||||
|
BasicAccount {
|
||||||
|
balance: 0.into(),
|
||||||
|
nonce: self.start_nonce,
|
||||||
|
code_hash: SHA3_EMPTY,
|
||||||
|
storage_root: SHA3_NULL_RLP
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: validate against request outputs.
|
// TODO: validate against request outputs.
|
||||||
// needs engine + env info as part of request.
|
// needs engine + env info as part of request.
|
||||||
let _ = sender.send(maybe_account);
|
let _ = sender.send(account);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Err(e) => warn!(target: "on_demand", "Error handling response for state request: {:?}", e),
|
Err(e) => warn!(target: "on_demand", "Error handling response for state request: {:?}", e),
|
||||||
@ -572,7 +583,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn detects_hangup() {
|
fn detects_hangup() {
|
||||||
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6))));
|
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6))));
|
||||||
let on_demand = OnDemand::new(cache);
|
let on_demand = OnDemand::new(cache, 0.into());
|
||||||
let result = on_demand.header_by_hash(&FakeContext, request::HeaderByHash(H256::default()));
|
let result = on_demand.header_by_hash(&FakeContext, request::HeaderByHash(H256::default()));
|
||||||
|
|
||||||
assert!(on_demand.orphaned_requests.read().len() == 1);
|
assert!(on_demand.orphaned_requests.read().len() == 1);
|
||||||
|
@ -67,7 +67,6 @@ impl IoHandler<ClientIoMessage> for QueueCull {
|
|||||||
|
|
||||||
let (sync, on_demand, txq) = (self.sync.clone(), self.on_demand.clone(), self.txq.clone());
|
let (sync, on_demand, txq) = (self.sync.clone(), self.on_demand.clone(), self.txq.clone());
|
||||||
let best_header = self.client.best_block_header();
|
let best_header = self.client.best_block_header();
|
||||||
let start_nonce = self.client.engine().account_start_nonce();
|
|
||||||
|
|
||||||
info!(target: "cull", "Attempting to cull queued transactions from {} senders.", senders.len());
|
info!(target: "cull", "Attempting to cull queued transactions from {} senders.", senders.len());
|
||||||
self.remote.spawn_with_timeout(move || {
|
self.remote.spawn_with_timeout(move || {
|
||||||
@ -75,8 +74,7 @@ impl IoHandler<ClientIoMessage> for QueueCull {
|
|||||||
// fetch the nonce of each sender in the queue.
|
// fetch the nonce of each sender in the queue.
|
||||||
let nonce_futures = senders.iter()
|
let nonce_futures = senders.iter()
|
||||||
.map(|&address| request::Account { header: best_header.clone(), address: address })
|
.map(|&address| request::Account { header: best_header.clone(), address: address })
|
||||||
.map(|request| on_demand.account(ctx, request))
|
.map(|request| on_demand.account(ctx, request).map(|acc| acc.nonce))
|
||||||
.map(move |fut| fut.map(move |x| x.map(|acc| acc.nonce).unwrap_or(start_nonce)))
|
|
||||||
.zip(senders.iter())
|
.zip(senders.iter())
|
||||||
.map(|(fut, &addr)| fut.map(move |nonce| (addr, nonce)));
|
.map(|(fut, &addr)| fut.map(move |nonce| (addr, nonce)));
|
||||||
|
|
||||||
|
@ -225,7 +225,8 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
|
|||||||
let cache = Arc::new(::util::Mutex::new(cache));
|
let cache = Arc::new(::util::Mutex::new(cache));
|
||||||
|
|
||||||
// start on_demand service.
|
// start on_demand service.
|
||||||
let on_demand = Arc::new(::light::on_demand::OnDemand::new(cache.clone()));
|
let account_start_nonce = service.client().engine().account_start_nonce();
|
||||||
|
let on_demand = Arc::new(::light::on_demand::OnDemand::new(cache.clone(), account_start_nonce));
|
||||||
|
|
||||||
// set network path.
|
// set network path.
|
||||||
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
|
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
|
||||||
|
@ -268,7 +268,7 @@ impl LightDispatcher {
|
|||||||
|
|
||||||
match nonce_future {
|
match nonce_future {
|
||||||
Some(x) =>
|
Some(x) =>
|
||||||
x.map(|acc| acc.map_or_else(Default::default, |acc| acc.nonce))
|
x.map(|acc| acc.nonce)
|
||||||
.map_err(|_| errors::no_light_peers())
|
.map_err(|_| errors::no_light_peers())
|
||||||
.boxed(),
|
.boxed(),
|
||||||
None => future::err(errors::network_disabled()).boxed()
|
None => future::err(errors::network_disabled()).boxed()
|
||||||
|
@ -173,12 +173,15 @@ impl EthClient {
|
|||||||
Some(hdr) => hdr,
|
Some(hdr) => hdr,
|
||||||
};
|
};
|
||||||
|
|
||||||
sync.with_context(|ctx| on_demand.account(ctx, request::Account {
|
let maybe_fut = sync.with_context(|ctx| on_demand.account(ctx, request::Account {
|
||||||
header: header,
|
header: header,
|
||||||
address: address,
|
address: address,
|
||||||
}))
|
}));
|
||||||
.map(|x| x.map_err(err_premature_cancel).boxed())
|
|
||||||
.unwrap_or_else(|| future::err(errors::network_disabled()).boxed())
|
match maybe_fut {
|
||||||
|
Some(fut) => fut.map(Some).map_err(err_premature_cancel).boxed(),
|
||||||
|
None => future::err(errors::network_disabled()).boxed(),
|
||||||
|
}
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user