Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Get ValidationPackage over network #727

Merged
merged 50 commits into from
Dec 8, 2018
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
29300b0
Break down handler.rs into separate files
lucksus Dec 5, 2018
91835da
DirectMessage enum
lucksus Dec 5, 2018
0fc470f
Action::SendDirectMessage
lucksus Dec 5, 2018
f8edd8e
Send handlers
lucksus Dec 5, 2018
4b67c54
Respond to validation request workflow
lucksus Dec 5, 2018
6e7aacc
Action::SendDirectMessage and reducer
lucksus Dec 5, 2018
fe9069b
rustfmt
lucksus Dec 5, 2018
0d56817
Clean up enum Actions
lucksus Dec 5, 2018
2033707
Action::GetValidationPackage with reducer and action creator
lucksus Dec 5, 2018
d90cdc9
Cleanup direct message handler
lucksus Dec 5, 2018
f23c858
Merge branch 'develop' into validation-over-network
lucksus Dec 5, 2018
2b5394e
Fix usage of sources
lucksus Dec 5, 2018
44699fc
Merge branch 'develop' into validation-over-network
lucksus Dec 6, 2018
bd7bf61
Add NetworkState::direct_message_connections and extract fn send_mess…
lucksus Dec 6, 2018
ec0ebbe
Reuse fn initialized() in every network reducer
lucksus Dec 6, 2018
a3f22f9
DRY out reducers by extracting fn send(NetworkState, ProtocolWrapper)
lucksus Dec 6, 2018
30b6d36
String key for direct_message_connections
lucksus Dec 6, 2018
7f8c454
Handler for DirectMessage::ValidationPackage -> Action::HandleGetVali…
lucksus Dec 6, 2018
6581aaf
reduce_handle_get_validation_package
lucksus Dec 6, 2018
35cf961
Action::ResolveDirectConnection with reducer and usage
lucksus Dec 6, 2018
579fbc5
Action comments
lucksus Dec 6, 2018
77c6d6f
Index new network reducers
lucksus Dec 6, 2018
6955178
test get_validation_package_roundtrip()
lucksus Dec 6, 2018
6f494af
Make sure address function of entry delegates to AgentId::address() i…
lucksus Dec 7, 2018
76fa842
Swap ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSendResult
lucksus Dec 7, 2018
c4fd511
Async funciton needs polling
lucksus Dec 7, 2018
b6c9a3f
Finalize test get_validation_package_roundtrip
lucksus Dec 7, 2018
f0726a7
Debug output when send failed
lucksus Dec 7, 2018
96c4862
rustfmt
lucksus Dec 7, 2018
b66068a
Change test fixture to expect real fake agent address
lucksus Dec 7, 2018
e812ae7
Adjust MockWorker's test for swap SendResult <> HandleSendResult
lucksus Dec 7, 2018
e5cda86
Merge branch 'develop' into validation-over-network
lucksus Dec 7, 2018
9d3efe5
Move initialized() into NetworkState
lucksus Dec 7, 2018
1aa4ab7
Reuse NetworkState::initialized() in action creators
lucksus Dec 7, 2018
728de2d
rustfmt
lucksus Dec 7, 2018
c1e226e
DirectMessageData instead of tuple
lucksus Dec 7, 2018
7f48728
Rustdoc comments
lucksus Dec 7, 2018
5e262ac
Revert "Swap ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSe…
lucksus Dec 7, 2018
7b020ee
Revert "Adjust MockWorker's test for swap SendResult <> HandleSendRes…
lucksus Dec 7, 2018
674cba2
Swap back ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSendR…
lucksus Dec 7, 2018
cebf97d
rustfmt
lucksus Dec 7, 2018
142076d
Error instead of panic
lucksus Dec 7, 2018
0165dac
lint
zippy Dec 7, 2018
95b8a63
merge develop
zippy Dec 8, 2018
551c237
Merge branch 'develop' into validation-over-network
Dec 8, 2018
39d5132
DirectMessage rustdoc
lucksus Dec 8, 2018
e70f13f
Logging
lucksus Dec 8, 2018
7673895
comments
lucksus Dec 8, 2018
4c51319
NetworkSettings struct
lucksus Dec 8, 2018
3b7f21d
Fix broken merge
lucksus Dec 8, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 82 additions & 16 deletions core/src/action.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::{
agent::state::AgentState,
context::Context,
network::state::NetworkState,
network::{direct_message::DirectMessage, state::NetworkState},
nucleus::{
state::{NucleusState, ValidationResult},
ExecuteZomeFnResponse, ZomeFnCall,
},
};
use holochain_core_types::{
cas::content::Address,
chain_header::ChainHeader,
dna::Dna,
entry::{Entry, EntryWithMeta},
error::HolochainError,
Expand Down Expand Up @@ -77,9 +78,38 @@ impl Hash for ActionWrapper {
/// All Actions for the Holochain Instance Store, according to Redux pattern.
#[derive(Clone, PartialEq, Debug)]
pub enum Action {
/// entry to Commit
/// MUST already have passed all callback checks
// ----------------
// Agent actions:
// ----------------
/// Writes an entry to the source chain.
/// Does not validate, assumes entry is valid.
Commit((Entry, Option<Address>)),

// -------------
// DHT actions:
// -------------
/// Adds an entry to the local DHT shard.
/// Does not validate, assumes entry is valid.
Hold(Entry),

/// Adds a link to the local DHT shard's meta/EAV storage
/// Does not validate, assumes link is valid.
AddLink(Link),

// ----------------
// Network actions:
// ----------------
/// Create a network proxy instance from the given JSON config.
/// 2nd and 3rd parameter are the DNA hash and the agent id
/// which are needed to register with the network.
InitNetwork((JsonString, String, String)),
lucksus marked this conversation as resolved.
Show resolved Hide resolved

/// Makes the network PUT the given entry to the DHT.
/// Distinguishes between different entry types and does
/// the right thing respectively.
/// (only publish for AppEntryType, publish and publish_meta for links etc)
Publish(Address),

/// GetEntry by address
GetEntry(Address),
///
Expand All @@ -88,16 +118,42 @@ pub enum Action {
RemoveEntry((Address, Address)),
///
GetEntryTimeout(Address),
/// link to add
AddLink(Link),

/// Lets the network module respond to a GET request.
/// Triggered from the corresponding workflow after retrieving the
/// requested entry from our local DHT shard.
RespondGet((GetDhtData, Option<EntryWithMeta>)),

/// get links from entry address and attribute-name
//GetLinks(GetLinksArgs),

/// execute a function in a zome WASM
ExecuteZomeFunction(ZomeFnCall),
/// return the result of a zome WASM function call
ReturnZomeFunctionResult(ExecuteZomeFnResponse),
/// We got a response for our GET request which needs to be
/// added to the state.
/// Triggered from the network handler.
HandleGetResult(DhtData),

/// Sends a direct message object to the given address.
/// 3rd parameter is the message id
lucksus marked this conversation as resolved.
Show resolved Hide resolved
/// 4th parameter is true for a response to a previous message, false for a new interaction
SendDirectMessage(DirectMessageData),

/// Makes the network module forget about the direct message
/// connection with the given ID.
/// Triggered when we got an answer to our initial DM.
ResolveDirectConnection(String),

/// Makes the network module DM the source of the given entry
/// and prepare for receiveing an answer
GetValidationPackage(ChainHeader),

/// Updates the state to hold the response that we got for
/// our previous request for a validation package.
/// Triggered from the network handler when we got the response.
HandleGetValidationPackage((Address, Option<ValidationPackage>)),

// ----------------
// Nucleus actions:
// ----------------
/// initialize an application from a Dna
/// not the same as genesis
/// may call genesis internally
Expand All @@ -106,26 +162,28 @@ pub enum Action {
/// the result is Some arbitrary string
ReturnInitializationResult(Option<String>),

/// execute a function in a zome WASM
ExecuteZomeFunction(ZomeFnCall),

/// return the result of a zome WASM function call
ReturnZomeFunctionResult(ExecuteZomeFnResponse),

/// Execute a zome function call called by another zome function
Call(ZomeFnCall),

/// A validation result that should be stored
/// A validation result is returned from a local callback execution
/// Key is an unique id of the calling context
/// and the hash of the entry that was validated
ReturnValidationResult(((snowflake::ProcessUniqueId, Address), ValidationResult)),

/// A validation package was created locally and is reported back
/// to be added to the state
ReturnValidationPackage(
(
snowflake::ProcessUniqueId,
Result<ValidationPackage, HolochainError>,
),
),

InitNetwork((JsonString, String, String)),
Publish(Address),
Hold(Entry),
RespondGet((GetDhtData, Option<EntryWithMeta>)),
HandleGetResult(DhtData),
}

/// function signature for action handler functions
Expand All @@ -136,6 +194,14 @@ pub type NetworkReduceFn = ReduceFn<NetworkState>;
pub type NucleusReduceFn = ReduceFn<NucleusState>;
pub type ReduceFn<S> = fn(Arc<Context>, &mut S, &ActionWrapper);

#[derive(Clone, PartialEq, Debug)]
pub struct DirectMessageData {
pub address: Address,
pub message: DirectMessage,
pub msg_id: String,
pub is_response: bool,
}

#[cfg(test)]
pub mod tests {

Expand Down
12 changes: 3 additions & 9 deletions core/src/network/actions/get_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ use futures::{
future::Future,
task::{LocalWaker, Poll},
};
use holochain_core_types::{
cas::content::Address,
entry::EntryWithMeta,
error::{HcResult, HolochainError},
};
use holochain_core_types::{cas::content::Address, entry::EntryWithMeta, error::HcResult};
use std::{
pin::{Pin, Unpin},
sync::Arc,
Expand Down Expand Up @@ -56,10 +52,8 @@ impl Future for GetEntryFuture {

fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
let state = self.context.state().unwrap().network();
if state.network.is_none() || state.dna_hash.is_none() || state.agent_id.is_none() {
return Poll::Ready(Err(HolochainError::IoError(
"Network not initialized".to_string(),
)));
if let Err(error) = state.initialized() {
return Poll::Ready(Err(error));
}
//
// TODO: connect the waker to state updates for performance reasons
Expand Down
67 changes: 67 additions & 0 deletions core/src/network/actions/get_validation_package.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
extern crate futures;
use crate::{
action::{Action, ActionWrapper},
context::Context,
instance::dispatch_action,
};
use futures::{
future::Future,
task::{LocalWaker, Poll},
};
use holochain_core_types::{
cas::content::Address, chain_header::ChainHeader, error::HcResult,
validation::ValidationPackage,
};
use std::{
pin::{Pin, Unpin},
sync::Arc,
};

/// GetValidationPackage Action Creator
/// This triggers the network module to retrieve the validation package for the
/// entry given by the header.
///
/// Returns a future that resolves to Option<ValidationPackage> (or HolochainError).
/// If that is None this means that we couldn't get a validation package from the source.
pub async fn get_validation_package(
header: ChainHeader,
context: &Arc<Context>,
) -> HcResult<Option<ValidationPackage>> {
let entry_address = header.entry_address().clone();
let action_wrapper = ActionWrapper::new(Action::GetValidationPackage(header));
dispatch_action(&context.action_channel, action_wrapper.clone());
await!(GetValidationPackageFuture {
context: context.clone(),
address: entry_address,
})
}

/// GetValidationPackageFuture resolves to an Option<ValidationPackage>
/// which would be None if the source responded with None, indicating that it
/// is not the source.
pub struct GetValidationPackageFuture {
context: Arc<Context>,
address: Address,
}

impl Unpin for GetValidationPackageFuture {}

impl Future for GetValidationPackageFuture {
type Output = HcResult<Option<ValidationPackage>>;

fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
let state = self.context.state().unwrap().network();
if let Err(error) = state.initialized() {
return Poll::Ready(Err(error));
}
//
// TODO: connect the waker to state updates for performance reasons
// See: https://github.com/holochain/holochain-rust/issues/314
//
lw.wake();
match state.get_validation_package_results.get(&self.address) {
Some(Some(result)) => Poll::Ready(result.clone()),
_ => Poll::Pending,
}
}
}
2 changes: 1 addition & 1 deletion core/src/network/actions/initialize_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async fn get_dna_and_agent(context: &Arc<Context>) -> Result<(String, String), H
let dna_hash = base64::encode(&dna.multihash()?);
Ok((dna_hash, agent_id))
}
/// InitNetwork Action Creator
/// Creates a network proxy object and stores DNA and agent hash in the network state.
pub async fn initialize_network(context: &Arc<Context>) -> Result<(), HolochainError> {
let (dna_hash, agent_id) = await!(get_dna_and_agent(context))?;
let action_wrapper = ActionWrapper::new(Action::InitNetwork((
Expand Down
1 change: 1 addition & 0 deletions core/src/network/actions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod get_entry;
pub mod get_validation_package;
pub mod initialize_network;
pub mod publish;

Expand Down
11 changes: 3 additions & 8 deletions core/src/network/actions/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ use futures::{
future::Future,
task::{LocalWaker, Poll},
};
use holochain_core_types::{
cas::content::Address,
error::{HcResult, HolochainError},
};
use holochain_core_types::{cas::content::Address, error::HcResult};
use std::{
pin::{Pin, Unpin},
sync::Arc,
Expand Down Expand Up @@ -46,10 +43,8 @@ impl Future for PublishFuture {

fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
let state = self.context.state().unwrap().network();
if state.network.is_none() || state.dna_hash.is_none() || state.agent_id.is_none() {
return Poll::Ready(Err(HolochainError::IoError(
"Network not initialized".to_string(),
)));
if let Err(error) = state.initialized() {
return Poll::Ready(Err(error));
}
//
// TODO: connect the waker to state updates for performance reasons
Expand Down
21 changes: 21 additions & 0 deletions core/src/network/direct_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use holochain_core_types::{cas::content::Address, validation::ValidationPackage};

/// These are the different kind of node-to-node messages
lucksus marked this conversation as resolved.
Show resolved Hide resolved
/// that can be send between Holochain nodes.
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub enum DirectMessage {
/// A custom direct message is something that gets triggered
/// from zome code, i.e. from the app.
/// Receiving such a messages triggers a WASM callback
Custom(String),

/// This message is used to ask another node (which needs to
/// be the author) for the validation package of a given entry.
RequestValidationPackage(Address),

/// With this message an author is responding to a
/// RequestValidationPackage message.
/// Option<> since there has to be a way to respond saying
/// "I can't"
ValidationPackage(Option<ValidationPackage>),
}
85 changes: 0 additions & 85 deletions core/src/network/handler.rs

This file was deleted.

Loading