serve epoch signals over network and check them
This commit is contained in:
@@ -1918,6 +1918,12 @@ impl ProvingBlockChainClient for Client {
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>> {
|
||||
// pending transitions are never deleted, and do not contain
|
||||
// finality proofs by definition.
|
||||
self.chain.read().get_pending_transition(hash).map(|pending| pending.proof)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Client {
|
||||
|
||||
@@ -778,6 +778,10 @@ impl ProvingBlockChainClient for TestBlockChainClient {
|
||||
fn prove_transaction(&self, _: SignedTransaction, _: BlockId) -> Option<(Bytes, Vec<DBValue>)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn epoch_signal(&self, _: H256) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl super::traits::EngineClient for TestBlockChainClient {
|
||||
|
||||
@@ -353,4 +353,7 @@ pub trait ProvingBlockChainClient: BlockChainClient {
|
||||
/// Returns the output of the call and a vector of database items necessary
|
||||
/// to reproduce it.
|
||||
fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec<DBValue>)>;
|
||||
|
||||
/// Get an epoch change signal by block hash.
|
||||
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ pub type Headers<'a> = Fn(H256) -> Option<Header> + 'a;
|
||||
pub type PendingTransitionStore<'a> = Fn(H256) -> Option<PendingTransition> + 'a;
|
||||
|
||||
/// Proof dependent on state.
|
||||
pub trait StateDependentProof {
|
||||
pub trait StateDependentProof: Send + Sync {
|
||||
/// Generate a proof, given the state.
|
||||
fn generate_proof(&self, caller: &Call) -> Result<Vec<u8>, String>;
|
||||
/// Check a proof generated elsewhere (potentially by a peer).
|
||||
@@ -135,7 +135,7 @@ pub enum Proof {
|
||||
/// Known proof (extracted from signal)
|
||||
Known(Vec<u8>),
|
||||
/// State dependent proof.
|
||||
WithState(Box<StateDependentProof>),
|
||||
WithState(Arc<StateDependentProof>),
|
||||
}
|
||||
|
||||
/// Generated epoch verifier.
|
||||
|
||||
@@ -47,19 +47,19 @@ lazy_static! {
|
||||
// state-dependent proofs for the safe contract:
|
||||
// only "first" proofs are such.
|
||||
struct StateProof {
|
||||
header: Header,
|
||||
header: Mutex<Header>,
|
||||
provider: Provider,
|
||||
}
|
||||
|
||||
impl ::engines::StateDependentProof for StateProof {
|
||||
fn generate_proof(&self, caller: &Call) -> Result<Vec<u8>, String> {
|
||||
prove_initial(&self.provider, &self.header, caller)
|
||||
prove_initial(&self.provider, &*self.header.lock(), caller)
|
||||
}
|
||||
|
||||
fn check_proof(&self, engine: &Engine, proof: &[u8]) -> Result<(), String> {
|
||||
let (header, state_items) = decode_first_proof(&UntrustedRlp::new(proof))
|
||||
.map_err(|e| format!("proof incorrectly encoded: {}", e))?;
|
||||
if header != self.header {
|
||||
if &header != &*self.header.lock(){
|
||||
return Err("wrong header in proof".into());
|
||||
}
|
||||
|
||||
@@ -330,11 +330,11 @@ impl ValidatorSet for ValidatorSafeContract {
|
||||
// transition to the first block of a contract requires finality but has no log event.
|
||||
if first {
|
||||
debug!(target: "engine", "signalling transition to fresh contract.");
|
||||
let state_proof = Box::new(StateProof {
|
||||
header: header.clone(),
|
||||
let state_proof = Arc::new(StateProof {
|
||||
header: Mutex::new(header.clone()),
|
||||
provider: self.provider.clone(),
|
||||
});
|
||||
return ::engines::EpochChange::Yes(::engines::Proof::WithState(state_proof as Box<_>));
|
||||
return ::engines::EpochChange::Yes(::engines::Proof::WithState(state_proof as Arc<_>));
|
||||
}
|
||||
|
||||
// otherwise, we're checking for logs.
|
||||
|
||||
Reference in New Issue
Block a user