network messages for transaction proof
This commit is contained in:
parent
92e5982127
commit
4158693470
@ -26,7 +26,7 @@ use io::TimerToken;
|
|||||||
use network::{NetworkProtocolHandler, NetworkContext, PeerId};
|
use network::{NetworkProtocolHandler, NetworkContext, PeerId};
|
||||||
use rlp::{RlpStream, Stream, UntrustedRlp, View};
|
use rlp::{RlpStream, Stream, UntrustedRlp, View};
|
||||||
use util::hash::H256;
|
use util::hash::H256;
|
||||||
use util::{Bytes, Mutex, RwLock, U256};
|
use util::{Bytes, DBValue, Mutex, RwLock, U256};
|
||||||
use time::{Duration, SteadyTime};
|
use time::{Duration, SteadyTime};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -211,6 +211,8 @@ pub trait Handler: Send + Sync {
|
|||||||
/// Called when a peer responds with header proofs. Each proof should be a block header coupled
|
/// Called when a peer responds with header proofs. Each proof should be a block header coupled
|
||||||
/// with a series of trie nodes is ascending order by distance from the root.
|
/// with a series of trie nodes is ascending order by distance from the root.
|
||||||
fn on_header_proofs(&self, _ctx: &EventContext, _req_id: ReqId, _proofs: &[(Bytes, Vec<Bytes>)]) { }
|
fn on_header_proofs(&self, _ctx: &EventContext, _req_id: ReqId, _proofs: &[(Bytes, Vec<Bytes>)]) { }
|
||||||
|
/// Called when a peer responds with a transaction proof. Each proof is a vector of state items.
|
||||||
|
fn on_transaction_proof(&self, _ctx: &EventContext, _req_id: ReqId, _state_items: &[DBValue]) { }
|
||||||
/// Called to "tick" the handler periodically.
|
/// Called to "tick" the handler periodically.
|
||||||
fn tick(&self, _ctx: &BasicContext) { }
|
fn tick(&self, _ctx: &BasicContext) { }
|
||||||
/// Called on abort. This signals to handlers that they should clean up
|
/// Called on abort. This signals to handlers that they should clean up
|
||||||
@ -535,6 +537,9 @@ impl LightProtocol {
|
|||||||
packet::GET_HEADER_PROOFS => self.get_header_proofs(peer, io, rlp),
|
packet::GET_HEADER_PROOFS => self.get_header_proofs(peer, io, rlp),
|
||||||
packet::HEADER_PROOFS => self.header_proofs(peer, io, rlp),
|
packet::HEADER_PROOFS => self.header_proofs(peer, io, rlp),
|
||||||
|
|
||||||
|
packet::GET_TRANSACTION_PROOF => self.get_transaction_proof(peer, io, rlp),
|
||||||
|
packet::TRANSACTION_PROOF => self.transaction_proof(peer, io, rlp),
|
||||||
|
|
||||||
packet::SEND_TRANSACTIONS => self.relay_transactions(peer, io, rlp),
|
packet::SEND_TRANSACTIONS => self.relay_transactions(peer, io, rlp),
|
||||||
|
|
||||||
other => {
|
other => {
|
||||||
@ -1178,6 +1183,87 @@ impl LightProtocol {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Receive a request for proof-of-execution.
|
||||||
|
fn get_transaction_proof(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||||
|
const MAX_GAS: usize = 10_000_000; // refuse to execute more than this amount of gas at once.
|
||||||
|
use util::Uint;
|
||||||
|
|
||||||
|
let peers = self.peers.read();
|
||||||
|
let peer = match peers.get(peer) {
|
||||||
|
Some(peer) => peer,
|
||||||
|
None => {
|
||||||
|
debug!(target: "les", "Ignoring request from unknown peer");
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
|
let req_id: u64 = raw.val_at(0)?;
|
||||||
|
|
||||||
|
let req = {
|
||||||
|
let req_rlp = raw.at(1)?;
|
||||||
|
request::TransactionProof {
|
||||||
|
at: req_rlp.val_at(0)?,
|
||||||
|
from: req_rlp.val_at(1)?,
|
||||||
|
action: if req_rlp.at(2)?.is_empty() {
|
||||||
|
Action::Create
|
||||||
|
} else {
|
||||||
|
Action::Call(req_rlp.val_at(2)?)
|
||||||
|
},
|
||||||
|
gas: ::std::cmp::min(req_rlp.val_at(3)?, MAX_GAS.into()),
|
||||||
|
gas_price: req_rlp.val_at(4)?,
|
||||||
|
value: req_rlp.val_at(5)?,
|
||||||
|
data: req_rlp.val_at(6)?,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// always charge the peer for all the gas.
|
||||||
|
peer.deduct_max(&self.flow_params, request::Kind::TransactionProof, req.gas.low_u64() as usize)?;
|
||||||
|
|
||||||
|
let response = match self.provider.transaction_proof(req) {
|
||||||
|
Some(res) => res,
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let cur_credits = peer.local_credits.current();
|
||||||
|
|
||||||
|
io.respond(packet::TRANSACTION_PROOF, {
|
||||||
|
let mut stream = RlpStream::new_list(3);
|
||||||
|
stream.append(&req_id).append(&cur_credits).begin_list(response.len());
|
||||||
|
|
||||||
|
for state_item in response {
|
||||||
|
stream.append(&&state_item[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.out()
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive a response for proof-of-execution.
|
||||||
|
fn transaction_proof(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
|
||||||
|
let id_guard = self.pre_verify_response(peer, request::Kind::HeaderProofs, &raw)?;
|
||||||
|
let raw_proof: Vec<DBValue> = raw.at(2)?.iter()
|
||||||
|
.map(|rlp| {
|
||||||
|
let mut db_val = DBValue::new();
|
||||||
|
db_val.append_slice(rlp.data()?);
|
||||||
|
Ok(db_val)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, ::rlp::DecoderError>>()?;
|
||||||
|
|
||||||
|
let req_id = id_guard.defuse();
|
||||||
|
for handler in &self.handlers {
|
||||||
|
handler.on_transaction_proof(&Ctx {
|
||||||
|
peer: *peer,
|
||||||
|
io: io,
|
||||||
|
proto: self,
|
||||||
|
}, req_id, &raw_proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Receive a set of transactions to relay.
|
// Receive a set of transactions to relay.
|
||||||
fn relay_transactions(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> {
|
fn relay_transactions(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> {
|
||||||
const MAX_TRANSACTIONS: usize = 256;
|
const MAX_TRANSACTIONS: usize = 256;
|
||||||
|
@ -114,7 +114,7 @@ impl RlpEncodable for CostTable {
|
|||||||
.append(&cost.1);
|
.append(&cost.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
s.begin_list(6);
|
s.begin_list(7);
|
||||||
|
|
||||||
append_cost(s, packet::GET_BLOCK_HEADERS, &self.headers);
|
append_cost(s, packet::GET_BLOCK_HEADERS, &self.headers);
|
||||||
append_cost(s, packet::GET_BLOCK_BODIES, &self.bodies);
|
append_cost(s, packet::GET_BLOCK_BODIES, &self.bodies);
|
||||||
@ -122,6 +122,7 @@ impl RlpEncodable for CostTable {
|
|||||||
append_cost(s, packet::GET_PROOFS, &self.state_proofs);
|
append_cost(s, packet::GET_PROOFS, &self.state_proofs);
|
||||||
append_cost(s, packet::GET_CONTRACT_CODES, &self.contract_codes);
|
append_cost(s, packet::GET_CONTRACT_CODES, &self.contract_codes);
|
||||||
append_cost(s, packet::GET_HEADER_PROOFS, &self.header_proofs);
|
append_cost(s, packet::GET_HEADER_PROOFS, &self.header_proofs);
|
||||||
|
append_cost(s, packet::GET_TRANSACTION_PROOF, &self.transaction_proof);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ use provider::Provider;
|
|||||||
use request::{self, Request, Headers};
|
use request::{self, Request, Headers};
|
||||||
|
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
use util::{Bytes, H256, U256};
|
use util::{Bytes, DBValue, H256, U256};
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -127,6 +127,10 @@ impl Provider for TestProvider {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transaction_proof(&self, _req: request::TransactionProof) -> Option<Vec<DBValue>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn ready_transactions(&self) -> Vec<PendingTransaction> {
|
fn ready_transactions(&self) -> Vec<PendingTransaction> {
|
||||||
self.0.client.ready_transactions()
|
self.0.client.ready_transactions()
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ impl<L: AsLightClient + Send + Sync> Provider for LightProvider<L> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_proof(&self, req: request::TransactionProof) -> Option<Vec<DBValue>> {
|
fn transaction_proof(&self, _req: request::TransactionProof) -> Option<Vec<DBValue>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user