From 29300b091c9b415cd1aa146b78e2e75afccde0d8 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 13:59:05 +0100 Subject: [PATCH 01/45] Break down handler.rs into separate files --- core/src/network/handler.rs | 61 ------------------------------- core/src/network/handler/get.rs | 30 +++++++++++++++ core/src/network/handler/mod.rs | 25 +++++++++++++ core/src/network/handler/store.rs | 35 ++++++++++++++++++ 4 files changed, 90 insertions(+), 61 deletions(-) delete mode 100644 core/src/network/handler.rs create mode 100644 core/src/network/handler/get.rs create mode 100644 core/src/network/handler/mod.rs create mode 100644 core/src/network/handler/store.rs diff --git a/core/src/network/handler.rs b/core/src/network/handler.rs deleted file mode 100644 index 3a0dd8ce64..0000000000 --- a/core/src/network/handler.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::{ - action::{Action, ActionWrapper}, - context::Context, - dht::actions::{add_link::add_link, hold::hold_entry}, - instance::dispatch_action, - network::util::EntryWithHeader, - nucleus, -}; -use futures::executor::block_on; -use holochain_core_types::{cas::content::Address, entry::Entry}; -use holochain_net_connection::{net_connection::NetHandler, protocol_wrapper::ProtocolWrapper}; -use std::{convert::TryFrom, sync::Arc}; - -pub fn create_handler(c: &Arc) -> NetHandler { - let context = c.clone(); - Box::new(move |message| { - let message = message.unwrap(); - let protocol_wrapper = ProtocolWrapper::try_from(message); - match protocol_wrapper { - Ok(ProtocolWrapper::StoreDht(dht_data)) => { - let entry_with_header: EntryWithHeader = - serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap()) - .unwrap(); - let _ = block_on(hold_entry(&entry_with_header.entry, &context.clone())); - } - Ok(ProtocolWrapper::StoreDhtMeta(dht_meta_data)) => { - let entry_with_header: EntryWithHeader = - serde_json::from_str(&serde_json::to_string(&dht_meta_data.content).unwrap()) - .unwrap(); - match dht_meta_data.attribute.as_ref() { - "link" => { - let link_add = match entry_with_header.entry { - Entry::LinkAdd(link_add) => link_add, - _ => unreachable!(), - }; - let link = link_add.link().clone(); - let _ = block_on(add_link(&link, &context.clone())); - } - _ => {} - } - } - Ok(ProtocolWrapper::GetDht(get_dht_data)) => { - let _ = block_on(nucleus::actions::get_entry::get_entry( - &context, - Address::from(get_dht_data.address.clone()), - )) - .map(|maybe_entry| { - let action_wrapper = - ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry))); - dispatch_action(&context.action_channel, action_wrapper.clone()); - }); - } - Ok(ProtocolWrapper::GetDhtResult(dht_data)) => { - let action_wrapper = ActionWrapper::new(Action::HandleGetResult(dht_data)); - dispatch_action(&context.action_channel, action_wrapper.clone()); - } - _ => {} - } - Ok(()) - }) -} diff --git a/core/src/network/handler/get.rs b/core/src/network/handler/get.rs new file mode 100644 index 0000000000..fb5cbab194 --- /dev/null +++ b/core/src/network/handler/get.rs @@ -0,0 +1,30 @@ +use crate::{ + action::{Action, ActionWrapper}, + context::Context, + instance::dispatch_action, + nucleus, +}; +use futures::executor::block_on; +use holochain_core_types::cas::content::Address; +use std::sync::Arc; + +use holochain_net_connection::protocol_wrapper::{ + DhtData, GetDhtData +}; + +pub fn handle_get_dht(get_dht_data: GetDhtData, context: Arc) { + let _ = block_on(nucleus::actions::get_entry::get_entry( + &context, + Address::from(get_dht_data.address.clone()), + )) + .map(|maybe_entry| { + let action_wrapper = + ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry))); + dispatch_action(&context.action_channel, action_wrapper.clone()); + }); +} + +pub fn handle_get_dht_result(dht_data: DhtData, context: Arc) { + let action_wrapper = ActionWrapper::new(Action::HandleGetResult(dht_data)); + dispatch_action(&context.action_channel, action_wrapper.clone()); +} \ No newline at end of file diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs new file mode 100644 index 0000000000..36b33a484a --- /dev/null +++ b/core/src/network/handler/mod.rs @@ -0,0 +1,25 @@ +pub mod get; +pub mod store; + +use crate::{ + context::Context, + network::handler::{store::*, get::*}, +}; +use holochain_net_connection::{net_connection::NetHandler, protocol_wrapper::ProtocolWrapper}; +use std::{convert::TryFrom, sync::Arc}; + +pub fn create_handler(c: &Arc) -> NetHandler { + let context = c.clone(); + Box::new(move |message| { + let message = message.unwrap(); + let protocol_wrapper = ProtocolWrapper::try_from(message); + match protocol_wrapper { + Ok(ProtocolWrapper::StoreDht(dht_data)) => handle_store_dht(dht_data, context.clone()), + Ok(ProtocolWrapper::StoreDhtMeta(dht_meta_data)) => handle_store_dht_meta(dht_meta_data, context.clone()), + Ok(ProtocolWrapper::GetDht(get_dht_data)) => handle_get_dht(get_dht_data, context.clone()), + Ok(ProtocolWrapper::GetDhtResult(dht_data)) => handle_get_dht_result(dht_data, context.clone()), + _ => {} + } + Ok(()) + }) +} diff --git a/core/src/network/handler/store.rs b/core/src/network/handler/store.rs new file mode 100644 index 0000000000..3a5d4c3507 --- /dev/null +++ b/core/src/network/handler/store.rs @@ -0,0 +1,35 @@ +use crate::{ + context::Context, + dht::actions::{add_link::add_link, hold::hold_entry}, +}; +use futures::executor::block_on; +use crate::network::util::EntryWithHeader; +use holochain_core_types::entry::Entry; +use holochain_net_connection::protocol_wrapper::{ + DhtData, DhtMetaData, +}; +use std::sync::Arc; + +pub fn handle_store_dht(dht_data: DhtData, context: Arc) { + let entry_with_header: EntryWithHeader = + serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap()) + .unwrap(); + let _ = block_on(hold_entry(&entry_with_header.entry, &context.clone())); +} + +pub fn handle_store_dht_meta(dht_meta_data: DhtMetaData, context: Arc) { + let entry_with_header: EntryWithHeader = + serde_json::from_str(&serde_json::to_string(&dht_meta_data.content).unwrap()) + .unwrap(); + match dht_meta_data.attribute.as_ref() { + "link" => { + let link_add = match entry_with_header.entry { + Entry::LinkAdd(link_add) => link_add, + _ => unreachable!(), + }; + let link = link_add.link().clone(); + let _ = block_on(add_link(&link, &context.clone())); + } + _ => {} + } +} \ No newline at end of file From 91835da39cd322e90fe32d93e27d4f609ecf7e6f Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 16:56:32 +0100 Subject: [PATCH 02/45] DirectMessage enum --- core/src/network/direct_message.rs | 23 +++++++++++++++++++++++ core/src/network/mod.rs | 1 + 2 files changed, 24 insertions(+) create mode 100644 core/src/network/direct_message.rs diff --git a/core/src/network/direct_message.rs b/core/src/network/direct_message.rs new file mode 100644 index 0000000000..5aaccd0a90 --- /dev/null +++ b/core/src/network/direct_message.rs @@ -0,0 +1,23 @@ +use holochain_core_types::{ + cas::content::Address, validation::ValidationPackage, +}; + +/// These are the different kind of node-to-node messages +/// 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), +} diff --git a/core/src/network/mod.rs b/core/src/network/mod.rs index 0c148afe7c..4921e64711 100644 --- a/core/src/network/mod.rs +++ b/core/src/network/mod.rs @@ -1,4 +1,5 @@ pub mod actions; +pub mod direct_message; pub mod handler; pub mod reducers; pub mod state; From 0fc470f8c9a5ea5ae611654b00eac368f5309179 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 16:56:57 +0100 Subject: [PATCH 03/45] Action::SendDirectMessage --- core/src/action.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/action.rs b/core/src/action.rs index a5331a7a4d..7b111031ab 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -1,7 +1,10 @@ use crate::{ agent::state::AgentState, context::Context, - network::state::NetworkState, + network::{ + direct_message::DirectMessage, + state::NetworkState + }, nucleus::{ state::{NucleusState, ValidationResult}, ExecuteZomeFnResponse, ZomeFnCall, @@ -117,6 +120,8 @@ pub enum Action { Hold(Entry), RespondGet((GetDhtData, Option)), HandleGetResult(DhtData), + + SendDirectMessage((Address, DirectMessage, String)), } /// function signature for action handler functions From f8edd8ee7095478ab07ff6a9d0d88f39988087be Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 16:57:51 +0100 Subject: [PATCH 04/45] Send handlers --- core/src/network/handler/mod.rs | 5 ++++- core/src/network/handler/send.rs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 core/src/network/handler/send.rs diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs index 36b33a484a..facfbac1c9 100644 --- a/core/src/network/handler/mod.rs +++ b/core/src/network/handler/mod.rs @@ -1,9 +1,10 @@ pub mod get; +pub mod send; pub mod store; use crate::{ context::Context, - network::handler::{store::*, get::*}, + network::handler::{store::*, get::*, send::*}, }; use holochain_net_connection::{net_connection::NetHandler, protocol_wrapper::ProtocolWrapper}; use std::{convert::TryFrom, sync::Arc}; @@ -18,6 +19,8 @@ pub fn create_handler(c: &Arc) -> NetHandler { Ok(ProtocolWrapper::StoreDhtMeta(dht_meta_data)) => handle_store_dht_meta(dht_meta_data, context.clone()), Ok(ProtocolWrapper::GetDht(get_dht_data)) => handle_get_dht(get_dht_data, context.clone()), Ok(ProtocolWrapper::GetDhtResult(dht_data)) => handle_get_dht_result(dht_data, context.clone()), + Ok(ProtocolWrapper::HandleSend(message_data)) => handle_send(message_data, context.clone()), + Ok(ProtocolWrapper::SendResult(message_data)) => handle_send_result(message_data, context.clone()), _ => {} } Ok(()) diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs new file mode 100644 index 0000000000..8770455286 --- /dev/null +++ b/core/src/network/handler/send.rs @@ -0,0 +1,35 @@ +use crate::{ + context::Context, + network::direct_message::DirectMessage, + workflows::respond_validation_package_request::respond_validation_package_request, +}; +use holochain_core_types::cas::content::Address; +use std::sync::Arc; + +use holochain_net_connection::protocol_wrapper::{ + MessageData +}; + +pub fn handle_send(message_data: MessageData, context: Arc) { + let message: DirectMessage = + serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()) + .unwrap(); + + match message { + DirectMessage::Custom(_) => unreachable!(), + DirectMessage::RequestValidationPackage(address) => { + respond_validation_package_request( + Address::from(message_data.from_agent_id), + message_data.msg_id, + address, + context.clone() + ); + }, + DirectMessage::ValidationPackage(_maybe_validation_package) => {} + } +} + +pub fn handle_send_result(_message_data: MessageData, _context: Arc) { + +} + From 4b67c542c48f9bbd178d3c8b31d51fc4be2e85ef Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 16:58:16 +0100 Subject: [PATCH 05/45] Respond to validation request workflow --- core/src/workflows/mod.rs | 1 + .../respond_validation_package_request.rs | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 core/src/workflows/respond_validation_package_request.rs diff --git a/core/src/workflows/mod.rs b/core/src/workflows/mod.rs index c5cfb92082..895eebddf4 100644 --- a/core/src/workflows/mod.rs +++ b/core/src/workflows/mod.rs @@ -1,2 +1,3 @@ pub mod author_entry; pub mod get_entry; +pub mod respond_validation_package_request; diff --git a/core/src/workflows/respond_validation_package_request.rs b/core/src/workflows/respond_validation_package_request.rs new file mode 100644 index 0000000000..59f9fe144b --- /dev/null +++ b/core/src/workflows/respond_validation_package_request.rs @@ -0,0 +1,47 @@ +use crate::{ + action::{Action, ActionWrapper}, + context::Context, + instance::dispatch_action, + network::direct_message::DirectMessage, + nucleus::actions::build_validation_package::build_validation_package, +}; + +use holochain_core_types::{ + cas::content::Address, + entry::Entry, + error::HolochainError, +}; +use std::{ + convert::TryFrom, + sync::Arc, +}; + +fn get_entry(address: &Address, context: &Arc) -> Result { + let raw = context.state() + .unwrap() + .agent() + .chain() + .content_storage() + .read() + .unwrap() + .fetch(address)? + .ok_or(HolochainError::ErrorGeneric("Entry not found".to_string()))?; + + Entry::try_from(raw) +} + +pub async fn respond_validation_package_request( + to_agent_id: Address, + msg_id: String, + requested_entry_address: Address, + context: Arc, +) { + let maybe_validation_package = match get_entry(&requested_entry_address, &context) { + Ok(entry) => await!(build_validation_package(&entry, &context)).ok(), + Err(_) => None + }; + + let direct_message = DirectMessage::ValidationPackage(maybe_validation_package); + let action_wrapper = ActionWrapper::new(Action::SendDirectMessage((to_agent_id, direct_message, msg_id))); + dispatch_action(&context.action_channel, action_wrapper); +} \ No newline at end of file From 6e7aacc08bfa262037d504bc08fcb0e4b075d21d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 19:46:25 +0100 Subject: [PATCH 06/45] Action::SendDirectMessage and reducer --- core/src/action.rs | 5 +- core/src/network/reducers/mod.rs | 1 + .../network/reducers/send_direct_message.rs | 71 +++++++++++++++++++ .../respond_validation_package_request.rs | 2 +- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 core/src/network/reducers/send_direct_message.rs diff --git a/core/src/action.rs b/core/src/action.rs index 7b111031ab..e2de0a5e3a 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -121,7 +121,10 @@ pub enum Action { RespondGet((GetDhtData, Option)), HandleGetResult(DhtData), - SendDirectMessage((Address, DirectMessage, String)), + /// Sends a direct message object to the given address. + /// 3rd parameter is the message id + /// 4th parameter is true for a response to a previous message, false for a new interaction + SendDirectMessage((Address, DirectMessage, String, bool)), } /// function signature for action handler functions diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 13205cf52d..912b82aee7 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -3,6 +3,7 @@ pub mod handle_get_result; pub mod init; pub mod publish; pub mod respond_get; +pub mod send_direct_message; use crate::{ action::{Action, ActionWrapper, NetworkReduceFn}, diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs new file mode 100644 index 0000000000..73a82a50c2 --- /dev/null +++ b/core/src/network/reducers/send_direct_message.rs @@ -0,0 +1,71 @@ +use boolinator::*; +use crate::{ + action::ActionWrapper, + context::Context, + network::{actions::ActionResponse, direct_message::DirectMessage, state::NetworkState}, +}; +use holochain_core_types::{ + error::HolochainError, +}; +use holochain_net_connection::{ + net_connection::NetConnection, + protocol_wrapper::{MessageData, ProtocolWrapper}, +}; +use std::sync::Arc; + +fn inner( + network_state: &mut NetworkState, + to_agent_id: String, + direct_message: &DirectMessage, + msg_id: String, + is_response: bool, +) -> Result<(), HolochainError> { + (network_state.network.is_some() + && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) + .ok_or("Network not initialized".to_string())?; + + let data = MessageData { + msg_id, + dna_hash: network_state.dna_hash.clone().unwrap(), + to_agent_id, + from_agent_id: network_state.agent_id.clone().unwrap(), + data: serde_json::from_str(&serde_json::to_string(direct_message).unwrap()).unwrap(), + }; + + let protocol_object = if is_response { + ProtocolWrapper::SendResult(data) + } else { + ProtocolWrapper::SendMessage(data) + }; + + network_state + .network + .as_mut() + .map(|network| { + network + .lock() + .unwrap() + .send(protocol_object.into()) + .map_err(|error| HolochainError::IoError(error.to_string())) + }) + .expect("Network has to be Some because of check above") +} + +pub fn reduce_send_direct_message( + _context: Arc, + network_state: &mut NetworkState, + action_wrapper: &ActionWrapper, +) { + let action = action_wrapper.action(); + let (to_agent_id, direct_message, msg_id, is_response) = unwrap_to!(action => crate::action::Action::SendDirectMessage); + + let result = inner(network_state, to_agent_id.to_string(), direct_message, msg_id.clone(), *is_response); + + network_state.actions.insert( + action_wrapper.clone(), + ActionResponse::RespondGet(match result { + Ok(_) => Ok(()), + Err(e) => Err(HolochainError::ErrorGeneric(e.to_string())), + }), + ); +} diff --git a/core/src/workflows/respond_validation_package_request.rs b/core/src/workflows/respond_validation_package_request.rs index 59f9fe144b..bc0040ec85 100644 --- a/core/src/workflows/respond_validation_package_request.rs +++ b/core/src/workflows/respond_validation_package_request.rs @@ -42,6 +42,6 @@ pub async fn respond_validation_package_request( }; let direct_message = DirectMessage::ValidationPackage(maybe_validation_package); - let action_wrapper = ActionWrapper::new(Action::SendDirectMessage((to_agent_id, direct_message, msg_id))); + let action_wrapper = ActionWrapper::new(Action::SendDirectMessage((to_agent_id, direct_message, msg_id, true))); dispatch_action(&context.action_channel, action_wrapper); } \ No newline at end of file From fe9069bb80993f1ded1dc7b14cb87671398a9bf8 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 19:57:17 +0100 Subject: [PATCH 07/45] rustfmt --- core/src/action.rs | 5 +--- core/src/network/direct_message.rs | 4 +-- core/src/network/handler/get.rs | 15 +++++------ core/src/network/handler/mod.rs | 22 +++++++++++----- core/src/network/handler/store.rs | 14 ++++------- .../network/reducers/send_direct_message.rs | 17 ++++++++----- .../respond_validation_package_request.rs | 25 +++++++++---------- 7 files changed, 52 insertions(+), 50 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index e2de0a5e3a..a42c6a70ae 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -1,10 +1,7 @@ use crate::{ agent::state::AgentState, context::Context, - network::{ - direct_message::DirectMessage, - state::NetworkState - }, + network::{direct_message::DirectMessage, state::NetworkState}, nucleus::{ state::{NucleusState, ValidationResult}, ExecuteZomeFnResponse, ZomeFnCall, diff --git a/core/src/network/direct_message.rs b/core/src/network/direct_message.rs index 5aaccd0a90..36893b1897 100644 --- a/core/src/network/direct_message.rs +++ b/core/src/network/direct_message.rs @@ -1,6 +1,4 @@ -use holochain_core_types::{ - cas::content::Address, validation::ValidationPackage, -}; +use holochain_core_types::{cas::content::Address, validation::ValidationPackage}; /// These are the different kind of node-to-node messages /// that can be send between Holochain nodes. diff --git a/core/src/network/handler/get.rs b/core/src/network/handler/get.rs index fb5cbab194..ccff6e07c2 100644 --- a/core/src/network/handler/get.rs +++ b/core/src/network/handler/get.rs @@ -8,23 +8,20 @@ use futures::executor::block_on; use holochain_core_types::cas::content::Address; use std::sync::Arc; -use holochain_net_connection::protocol_wrapper::{ - DhtData, GetDhtData -}; +use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData}; pub fn handle_get_dht(get_dht_data: GetDhtData, context: Arc) { let _ = block_on(nucleus::actions::get_entry::get_entry( &context, Address::from(get_dht_data.address.clone()), )) - .map(|maybe_entry| { - let action_wrapper = - ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry))); - dispatch_action(&context.action_channel, action_wrapper.clone()); - }); + .map(|maybe_entry| { + let action_wrapper = ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry))); + dispatch_action(&context.action_channel, action_wrapper.clone()); + }); } pub fn handle_get_dht_result(dht_data: DhtData, context: Arc) { let action_wrapper = ActionWrapper::new(Action::HandleGetResult(dht_data)); dispatch_action(&context.action_channel, action_wrapper.clone()); -} \ No newline at end of file +} diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs index facfbac1c9..5ca0a40c8c 100644 --- a/core/src/network/handler/mod.rs +++ b/core/src/network/handler/mod.rs @@ -4,7 +4,7 @@ pub mod store; use crate::{ context::Context, - network::handler::{store::*, get::*, send::*}, + network::handler::{get::*, send::*, store::*}, }; use holochain_net_connection::{net_connection::NetHandler, protocol_wrapper::ProtocolWrapper}; use std::{convert::TryFrom, sync::Arc}; @@ -16,11 +16,21 @@ pub fn create_handler(c: &Arc) -> NetHandler { let protocol_wrapper = ProtocolWrapper::try_from(message); match protocol_wrapper { Ok(ProtocolWrapper::StoreDht(dht_data)) => handle_store_dht(dht_data, context.clone()), - Ok(ProtocolWrapper::StoreDhtMeta(dht_meta_data)) => handle_store_dht_meta(dht_meta_data, context.clone()), - Ok(ProtocolWrapper::GetDht(get_dht_data)) => handle_get_dht(get_dht_data, context.clone()), - Ok(ProtocolWrapper::GetDhtResult(dht_data)) => handle_get_dht_result(dht_data, context.clone()), - Ok(ProtocolWrapper::HandleSend(message_data)) => handle_send(message_data, context.clone()), - Ok(ProtocolWrapper::SendResult(message_data)) => handle_send_result(message_data, context.clone()), + Ok(ProtocolWrapper::StoreDhtMeta(dht_meta_data)) => { + handle_store_dht_meta(dht_meta_data, context.clone()) + } + Ok(ProtocolWrapper::GetDht(get_dht_data)) => { + handle_get_dht(get_dht_data, context.clone()) + } + Ok(ProtocolWrapper::GetDhtResult(dht_data)) => { + handle_get_dht_result(dht_data, context.clone()) + } + Ok(ProtocolWrapper::HandleSend(message_data)) => { + handle_send(message_data, context.clone()) + } + Ok(ProtocolWrapper::SendResult(message_data)) => { + handle_send_result(message_data, context.clone()) + } _ => {} } Ok(()) diff --git a/core/src/network/handler/store.rs b/core/src/network/handler/store.rs index 3a5d4c3507..db3a8e4484 100644 --- a/core/src/network/handler/store.rs +++ b/core/src/network/handler/store.rs @@ -1,26 +1,22 @@ use crate::{ context::Context, dht::actions::{add_link::add_link, hold::hold_entry}, + network::util::EntryWithHeader, }; use futures::executor::block_on; -use crate::network::util::EntryWithHeader; use holochain_core_types::entry::Entry; -use holochain_net_connection::protocol_wrapper::{ - DhtData, DhtMetaData, -}; +use holochain_net_connection::protocol_wrapper::{DhtData, DhtMetaData}; use std::sync::Arc; pub fn handle_store_dht(dht_data: DhtData, context: Arc) { let entry_with_header: EntryWithHeader = - serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap()) - .unwrap(); + serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap()).unwrap(); let _ = block_on(hold_entry(&entry_with_header.entry, &context.clone())); } pub fn handle_store_dht_meta(dht_meta_data: DhtMetaData, context: Arc) { let entry_with_header: EntryWithHeader = - serde_json::from_str(&serde_json::to_string(&dht_meta_data.content).unwrap()) - .unwrap(); + serde_json::from_str(&serde_json::to_string(&dht_meta_data.content).unwrap()).unwrap(); match dht_meta_data.attribute.as_ref() { "link" => { let link_add = match entry_with_header.entry { @@ -32,4 +28,4 @@ pub fn handle_store_dht_meta(dht_meta_data: DhtMetaData, context: Arc) } _ => {} } -} \ No newline at end of file +} diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 73a82a50c2..42f94f5c97 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -4,9 +4,7 @@ use crate::{ context::Context, network::{actions::ActionResponse, direct_message::DirectMessage, state::NetworkState}, }; -use holochain_core_types::{ - error::HolochainError, -}; +use holochain_core_types::error::HolochainError; use holochain_net_connection::{ net_connection::NetConnection, protocol_wrapper::{MessageData, ProtocolWrapper}, @@ -22,7 +20,7 @@ fn inner( ) -> Result<(), HolochainError> { (network_state.network.is_some() && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + .ok_or("Network not initialized".to_string())?; let data = MessageData { msg_id, @@ -57,9 +55,16 @@ pub fn reduce_send_direct_message( action_wrapper: &ActionWrapper, ) { let action = action_wrapper.action(); - let (to_agent_id, direct_message, msg_id, is_response) = unwrap_to!(action => crate::action::Action::SendDirectMessage); + let (to_agent_id, direct_message, msg_id, is_response) = + unwrap_to!(action => crate::action::Action::SendDirectMessage); - let result = inner(network_state, to_agent_id.to_string(), direct_message, msg_id.clone(), *is_response); + let result = inner( + network_state, + to_agent_id.to_string(), + direct_message, + msg_id.clone(), + *is_response, + ); network_state.actions.insert( action_wrapper.clone(), diff --git a/core/src/workflows/respond_validation_package_request.rs b/core/src/workflows/respond_validation_package_request.rs index bc0040ec85..2f81d56618 100644 --- a/core/src/workflows/respond_validation_package_request.rs +++ b/core/src/workflows/respond_validation_package_request.rs @@ -6,18 +6,12 @@ use crate::{ nucleus::actions::build_validation_package::build_validation_package, }; -use holochain_core_types::{ - cas::content::Address, - entry::Entry, - error::HolochainError, -}; -use std::{ - convert::TryFrom, - sync::Arc, -}; +use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; +use std::{convert::TryFrom, sync::Arc}; fn get_entry(address: &Address, context: &Arc) -> Result { - let raw = context.state() + let raw = context + .state() .unwrap() .agent() .chain() @@ -38,10 +32,15 @@ pub async fn respond_validation_package_request( ) { let maybe_validation_package = match get_entry(&requested_entry_address, &context) { Ok(entry) => await!(build_validation_package(&entry, &context)).ok(), - Err(_) => None + Err(_) => None, }; let direct_message = DirectMessage::ValidationPackage(maybe_validation_package); - let action_wrapper = ActionWrapper::new(Action::SendDirectMessage((to_agent_id, direct_message, msg_id, true))); + let action_wrapper = ActionWrapper::new(Action::SendDirectMessage(( + to_agent_id, + direct_message, + msg_id, + true, + ))); dispatch_action(&context.action_channel, action_wrapper); -} \ No newline at end of file +} From 0d568176e3684595983d653f267104ca074f6f65 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 21:34:46 +0100 Subject: [PATCH 08/45] Clean up enum Actions --- core/src/action.rs | 70 +++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index a42c6a70ae..e126166646 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -72,22 +72,51 @@ 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), + + + // ------------- + // 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: + // ---------------- + + InitNetwork((JsonString, String, String)), + Publish(Address), + /// GetEntry by address GetEntry(Address), GetEntryTimeout(Address), - /// link to add - AddLink(Link), - /// get links from entry address and attribute-name - //GetLinks(GetLinksArgs), + RespondGet((GetDhtData, Option)), + HandleGetResult(DhtData), + + /// Sends a direct message object to the given address. + /// 3rd parameter is the message id + /// 4th parameter is true for a response to a previous message, false for a new interaction + SendDirectMessage((Address, DirectMessage, String, bool)), - /// execute a function in a zome WASM - ExecuteZomeFunction(ZomeFnCall), - /// return the result of a zome WASM function call - ReturnZomeFunctionResult(ExecuteZomeFnResponse), + + // ---------------- + // Nucleus actions: + // ---------------- /// initialize an application from a Dna /// not the same as genesis @@ -97,31 +126,28 @@ pub enum Action { /// the result is Some arbitrary string ReturnInitializationResult(Option), + /// 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, ), ), - - InitNetwork((JsonString, String, String)), - Publish(Address), - Hold(Entry), - RespondGet((GetDhtData, Option)), - HandleGetResult(DhtData), - - /// Sends a direct message object to the given address. - /// 3rd parameter is the message id - /// 4th parameter is true for a response to a previous message, false for a new interaction - SendDirectMessage((Address, DirectMessage, String, bool)), } /// function signature for action handler functions From 2033707f6521b810b2fc2f79a2946b2ac484f74d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 22:12:34 +0100 Subject: [PATCH 09/45] Action::GetValidationPackage with reducer and action creator --- core/src/action.rs | 4 +- .../network/actions/get_validation_package.rs | 67 +++++++++++++++++++ core/src/network/actions/mod.rs | 1 + .../reducers/get_validation_package.rs | 65 ++++++++++++++++++ core/src/network/reducers/mod.rs | 1 + core/src/network/state.rs | 18 ++++- 6 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 core/src/network/actions/get_validation_package.rs create mode 100644 core/src/network/reducers/get_validation_package.rs diff --git a/core/src/action.rs b/core/src/action.rs index e126166646..a2fe25c68a 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -8,7 +8,8 @@ use crate::{ }, }; use holochain_core_types::{ - cas::content::Address, dna::Dna, entry::Entry, error::HolochainError, json::JsonString, + cas::content::Address, chain_header::ChainHeader, dna::Dna, entry::Entry, + error::HolochainError, json::JsonString, link::Link, validation::ValidationPackage, }; use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData}; @@ -113,6 +114,7 @@ pub enum Action { /// 4th parameter is true for a response to a previous message, false for a new interaction SendDirectMessage((Address, DirectMessage, String, bool)), + GetValidationPackage(ChainHeader), // ---------------- // Nucleus actions: diff --git a/core/src/network/actions/get_validation_package.rs b/core/src/network/actions/get_validation_package.rs new file mode 100644 index 0000000000..38d99599e2 --- /dev/null +++ b/core/src/network/actions/get_validation_package.rs @@ -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, HolochainError}, + 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 (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) -> HcResult> { + 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, + }) +} + +/// PublishFuture resolves to ActionResponse +/// Tracks the state for a response to its ActionWrapper +pub struct GetValidationPackageFuture { + context: Arc, + address: Address, +} + +impl Unpin for GetValidationPackageFuture {} + +impl Future for GetValidationPackageFuture { + type Output = HcResult>; + + fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { + 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(), + ))); + } + // + // 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, + } + } +} diff --git a/core/src/network/actions/mod.rs b/core/src/network/actions/mod.rs index a4b36d9e11..34d1ac147a 100644 --- a/core/src/network/actions/mod.rs +++ b/core/src/network/actions/mod.rs @@ -1,4 +1,5 @@ pub mod get_entry; +pub mod get_validation_package; pub mod initialize_network; pub mod publish; diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs new file mode 100644 index 0000000000..cde12bdbd5 --- /dev/null +++ b/core/src/network/reducers/get_validation_package.rs @@ -0,0 +1,65 @@ +use boolinator::*; +use crate::{ + action::ActionWrapper, context::Context, + network::{ + direct_message::DirectMessage, + state::NetworkState + }, +}; +use holochain_core_types::{ + chain_header::ChainHeader, + error::HolochainError, +}; +use holochain_net_connection::{ + net_connection::NetConnection, + protocol_wrapper::{MessageData, ProtocolWrapper}, +}; +use std::sync::Arc; + +fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), HolochainError> { + (network_state.network.is_some() + && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) + .ok_or("Network not initialized".to_string())?; + + let source_address = header.sources.first(); + let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); + + let data = MessageData { + msg_id: "".to_string(), + dna_hash: network_state.dna_hash.clone().unwrap(), + to_agent_id: source_address, + from_agent_id: network_state.agent_id.clone().unwrap(), + data: serde_json::from_str(&serde_json::to_string(&direct_message).unwrap()).unwrap(), + }; + + network_state + .network + .as_mut() + .map(|network| { + network + .lock() + .unwrap() + .send(ProtocolWrapper::SendMessage(data).into()) + .map_err(|error| HolochainError::IoError(error.to_string())) + }) + .expect("Network has to be Some because of check above") +} + +pub fn reduce_get_validation_package( + _context: Arc, + network_state: &mut NetworkState, + action_wrapper: &ActionWrapper, +) { + let action = action_wrapper.action(); + let header = unwrap_to!(action => crate::action::Action::GetValidationPackage); + let entry_address = header.entry_address().clone(); + + let result = match inner(network_state, header) { + Ok(()) => None, + Err(err) => Some(Err(err)), + }; + + network_state + .get_validation_package_results + .insert(entry_address, result); +} diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 912b82aee7..eec8b1c651 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -1,4 +1,5 @@ pub mod get_entry; +pub mod get_validation_package; pub mod handle_get_result; pub mod init; pub mod publish; diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 772b45ed36..8ec5cd7679 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -1,5 +1,5 @@ use crate::{action::ActionWrapper, network::actions::ActionResponse}; -use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; +use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError, validation::ValidationPackage}; use holochain_net::p2p_network::P2pNetwork; use snowflake; use std::{ @@ -8,8 +8,22 @@ use std::{ }; type Actions = HashMap; + +/// This represents the state of a get_entry network process: +/// None: process started, but no response yet from the network +/// Some(Err(_)): there was a problem at some point +/// Some(Ok(None)): no problem but also no entry -> it does not exist +/// Some(Ok(Some(entry))): we have it type GetEntryResult = Option, HolochainError>>; +/// This represents the state of a get_validation_package network process: +/// None: process started, but no response yet from the network +/// Some(Err(_)): there was a problem at some point +/// Some(Ok(None)): no error but also no validation package -> we seem to have asked the wrong +/// agent which actually should not happen. Something weird is going on. +/// Some(Ok(Some(entry))): we have it +type GetValidationPackageResult = Option, HolochainError>>; + #[derive(Clone, Debug)] pub struct NetworkState { /// every action and the result of that action @@ -20,6 +34,7 @@ pub struct NetworkState { pub dna_hash: Option, pub agent_id: Option, pub get_entry_results: HashMap, + pub get_validation_package_results: HashMap, id: snowflake::ProcessUniqueId, } @@ -37,6 +52,7 @@ impl NetworkState { dna_hash: None, agent_id: None, get_entry_results: HashMap::new(), + get_validation_package_results: HashMap::new(), id: snowflake::ProcessUniqueId::new(), } } From d90cdc95352a663d6c5a94b65e186967cd979c7c Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 22:13:16 +0100 Subject: [PATCH 10/45] Cleanup direct message handler --- core/src/network/handler/send.rs | 52 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index 8770455286..18a4f8c35d 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -1,35 +1,55 @@ use crate::{ - context::Context, - network::direct_message::DirectMessage, + context::Context, network::direct_message::DirectMessage, workflows::respond_validation_package_request::respond_validation_package_request, }; use holochain_core_types::cas::content::Address; use std::sync::Arc; -use holochain_net_connection::protocol_wrapper::{ - MessageData -}; +use holochain_net_connection::protocol_wrapper::MessageData; + +fn log>(context: &Arc, msg: T) { + context + .logger + .lock() + .unwrap() + .log(msg.into()); +} +/// We got a ProtocolWrapper::SendMessage, this means somebody initiates message roundtrip +/// -> we are being called pub fn handle_send(message_data: MessageData, context: Arc) { let message: DirectMessage = - serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()) - .unwrap(); + serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()).unwrap(); match message { - DirectMessage::Custom(_) => unreachable!(), + DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), DirectMessage::RequestValidationPackage(address) => { respond_validation_package_request( - Address::from(message_data.from_agent_id), - message_data.msg_id, - address, - context.clone() + Address::from(message_data.from_agent_id), + message_data.msg_id, + address, + context.clone(), ); - }, - DirectMessage::ValidationPackage(_maybe_validation_package) => {} + } + DirectMessage::ValidationPackage(_) => log( + &context, + "Got DirectMessage::ValidationPackage as initial message. This should not happen." + ), } } -pub fn handle_send_result(_message_data: MessageData, _context: Arc) { +/// We got a ProtocolWrapper::SendResult, this means somebody has responded to our message +/// -> we called and this is the answer +pub fn handle_send_result(message_data: MessageData, context: Arc) { + let message: DirectMessage = + serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()).unwrap(); + match message { + DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), + DirectMessage::RequestValidationPackage(_) => log( + &context, + "Got DirectMessage::RequestValidationPackage as a response. This should not happen." + ), + DirectMessage::ValidationPackage(maybe_validation_package) => {} + } } - From 2b5394e59f5b3c7c8a5cc8d52a7708fe9487324d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Wed, 5 Dec 2018 22:22:42 +0100 Subject: [PATCH 11/45] Fix usage of sources --- core/src/network/reducers/get_validation_package.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index cde12bdbd5..d7a6405a0e 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -21,13 +21,13 @@ fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), H && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) .ok_or("Network not initialized".to_string())?; - let source_address = header.sources.first(); + let source_address = header.sources().first().expect("A header must have at least one source"); let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); let data = MessageData { msg_id: "".to_string(), dna_hash: network_state.dna_hash.clone().unwrap(), - to_agent_id: source_address, + to_agent_id: source_address.to_string(), from_agent_id: network_state.agent_id.clone().unwrap(), data: serde_json::from_str(&serde_json::to_string(&direct_message).unwrap()).unwrap(), }; From bd7bf6148ee4ab8a588b6a693a22f618a520711d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 16:00:41 +0100 Subject: [PATCH 12/45] Add NetworkState::direct_message_connections and extract fn send_message() (and initialized()) from get_validation_package reducer --- .../reducers/get_validation_package.rs | 30 ++---------- core/src/network/reducers/mod.rs | 47 +++++++++++++++++++ core/src/network/state.rs | 10 +++- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index d7a6405a0e..289e2a25eb 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -1,8 +1,8 @@ -use boolinator::*; use crate::{ action::ActionWrapper, context::Context, network::{ direct_message::DirectMessage, + reducers::{initialized, send_message}, state::NetworkState }, }; @@ -10,39 +10,15 @@ use holochain_core_types::{ chain_header::ChainHeader, error::HolochainError, }; -use holochain_net_connection::{ - net_connection::NetConnection, - protocol_wrapper::{MessageData, ProtocolWrapper}, -}; use std::sync::Arc; fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let source_address = header.sources().first().expect("A header must have at least one source"); let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); - let data = MessageData { - msg_id: "".to_string(), - dna_hash: network_state.dna_hash.clone().unwrap(), - to_agent_id: source_address.to_string(), - from_agent_id: network_state.agent_id.clone().unwrap(), - data: serde_json::from_str(&serde_json::to_string(&direct_message).unwrap()).unwrap(), - }; - - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::SendMessage(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + send_message(network_state, source_address, direct_message) } pub fn reduce_get_validation_package( diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index eec8b1c651..ea44caeb00 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -6,10 +6,12 @@ pub mod publish; pub mod respond_get; pub mod send_direct_message; +use boolinator::*; use crate::{ action::{Action, ActionWrapper, NetworkReduceFn}, context::Context, network::{ + direct_message::DirectMessage, reducers::{ get_entry::{reduce_get_entry, reduce_get_entry_timeout}, handle_get_result::reduce_handle_get_result, @@ -20,6 +22,15 @@ use crate::{ state::NetworkState, }, }; +use holochain_core_types::{ + cas::content::Address, + error::HolochainError, +}; +use holochain_net_connection::{ + net_connection::NetConnection, + protocol_wrapper::{MessageData, ProtocolWrapper}, +}; +use snowflake::ProcessUniqueId; use std::sync::Arc; /// maps incoming action to the correct handler @@ -50,3 +61,39 @@ pub fn reduce( None => old_state, } } + +pub fn initialized(network_state: &NetworkState) -> Result<(), HolochainError> { + (network_state.network.is_some() + && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) + .ok_or(HolochainError::ErrorGeneric("Network not initialized".to_string())) +} + +pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, message: DirectMessage) -> Result<(), HolochainError> { + let id = ProcessUniqueId::new(); + + let data = MessageData { + msg_id: id.to_string(), + dna_hash: network_state.dna_hash.clone().unwrap(), + to_agent_id: to_agent_id.to_string(), + from_agent_id: network_state.agent_id.clone().unwrap(), + data: serde_json::from_str(&serde_json::to_string(&message).unwrap()).unwrap(), + }; + + let _ = network_state + .network + .as_mut() + .map(|network| { + network + .lock() + .unwrap() + .send(ProtocolWrapper::SendMessage(data).into()) + .map_err(|error| HolochainError::IoError(error.to_string())) + }) + .ok_or(HolochainError::ErrorGeneric("Network has to be Some because of check above".to_string()))?; + + network_state + .direct_message_connections + .insert(id, message); + + Ok(()) +} \ No newline at end of file diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 8ec5cd7679..52e9c2c7f7 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -1,4 +1,10 @@ -use crate::{action::ActionWrapper, network::actions::ActionResponse}; +use crate::{ + action::ActionWrapper, + network::{ + actions::ActionResponse, + direct_message::DirectMessage, + } +}; use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError, validation::ValidationPackage}; use holochain_net::p2p_network::P2pNetwork; use snowflake; @@ -35,6 +41,7 @@ pub struct NetworkState { pub agent_id: Option, pub get_entry_results: HashMap, pub get_validation_package_results: HashMap, + pub direct_message_connections: HashMap, id: snowflake::ProcessUniqueId, } @@ -53,6 +60,7 @@ impl NetworkState { agent_id: None, get_entry_results: HashMap::new(), get_validation_package_results: HashMap::new(), + direct_message_connections: HashMap::new(), id: snowflake::ProcessUniqueId::new(), } } From ec0ebbe8b70065848c0241508b70f50a94b1f5b2 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 16:04:32 +0100 Subject: [PATCH 13/45] Reuse fn initialized() in every network reducer --- core/src/network/reducers/get_entry.rs | 13 ++++++++----- core/src/network/reducers/handle_get_result.rs | 13 ++++++++----- core/src/network/reducers/publish.rs | 12 +++++++----- core/src/network/reducers/respond_get.rs | 7 ++----- core/src/network/reducers/send_direct_message.rs | 7 ++----- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index 19f9730416..bd81638ab4 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -1,5 +1,10 @@ -use boolinator::*; -use crate::{action::ActionWrapper, context::Context, network::state::NetworkState}; +use crate::{ + action::ActionWrapper, context::Context, + network::{ + reducers::initialized, + state::NetworkState, + } +}; use holochain_core_types::{cas::content::Address, error::HolochainError}; use holochain_net_connection::{ net_connection::NetConnection, @@ -8,9 +13,7 @@ use holochain_net_connection::{ use std::sync::Arc; fn inner(network_state: &mut NetworkState, address: &Address) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let data = GetDhtData { msg_id: "?".to_string(), diff --git a/core/src/network/reducers/handle_get_result.rs b/core/src/network/reducers/handle_get_result.rs index dfb5086790..1bfa13ea04 100644 --- a/core/src/network/reducers/handle_get_result.rs +++ b/core/src/network/reducers/handle_get_result.rs @@ -1,5 +1,10 @@ -use boolinator::*; -use crate::{action::ActionWrapper, context::Context, network::state::NetworkState}; +use crate::{ + action::ActionWrapper, context::Context, + network::{ + reducers::initialized, + state::NetworkState, + } +}; use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; use holochain_net_connection::protocol_wrapper::DhtData; use std::sync::Arc; @@ -8,9 +13,7 @@ fn inner( network_state: &mut NetworkState, dht_data: &DhtData, ) -> Result, HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let entry: Option = serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap())?; diff --git a/core/src/network/reducers/publish.rs b/core/src/network/reducers/publish.rs index 193e5c6540..d5ab590591 100644 --- a/core/src/network/reducers/publish.rs +++ b/core/src/network/reducers/publish.rs @@ -1,8 +1,12 @@ -use boolinator::*; use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, state::NetworkState, util}, + network::{ + actions::ActionResponse, + reducers::initialized, + state::NetworkState, + util, + }, }; use holochain_core_types::{ cas::content::{Address, AddressableContent}, @@ -89,9 +93,7 @@ fn inner( network_state: &mut NetworkState, address: &Address, ) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let (entry, header) = util::entry_with_header(&address, &context)?; diff --git a/core/src/network/reducers/respond_get.rs b/core/src/network/reducers/respond_get.rs index 31fb11d23e..5e9590327c 100644 --- a/core/src/network/reducers/respond_get.rs +++ b/core/src/network/reducers/respond_get.rs @@ -1,8 +1,7 @@ -use boolinator::*; use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, state::NetworkState}, + network::{actions::ActionResponse, reducers::initialized, state::NetworkState}, }; use holochain_core_types::{entry::Entry, error::HolochainError}; use holochain_net_connection::{ @@ -16,9 +15,7 @@ fn inner( get_dht_data: &GetDhtData, maybe_entry: &Option, ) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let data = DhtData { msg_id: get_dht_data.msg_id.clone(), diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 42f94f5c97..83a8039a07 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -1,8 +1,7 @@ -use boolinator::*; use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, direct_message::DirectMessage, state::NetworkState}, + network::{actions::ActionResponse, direct_message::DirectMessage, reducers::initialized, state::NetworkState}, }; use holochain_core_types::error::HolochainError; use holochain_net_connection::{ @@ -18,9 +17,7 @@ fn inner( msg_id: String, is_response: bool, ) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or("Network not initialized".to_string())?; + initialized(network_state)?; let data = MessageData { msg_id, From a3f22f991b90dca1c438d6c8b3e03d5e69034675 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 16:16:27 +0100 Subject: [PATCH 14/45] DRY out reducers by extracting fn send(NetworkState, ProtocolWrapper) --- core/src/network/reducers/get_entry.rs | 19 ++-------- core/src/network/reducers/mod.rs | 26 ++++++++------ core/src/network/reducers/publish.rs | 36 +++---------------- core/src/network/reducers/respond_get.rs | 19 ++-------- .../network/reducers/send_direct_message.rs | 25 ++----------- 5 files changed, 29 insertions(+), 96 deletions(-) diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index bd81638ab4..7e86a72318 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -1,13 +1,12 @@ use crate::{ action::ActionWrapper, context::Context, network::{ - reducers::initialized, + reducers::{initialized, send}, state::NetworkState, } }; use holochain_core_types::{cas::content::Address, error::HolochainError}; use holochain_net_connection::{ - net_connection::NetConnection, protocol_wrapper::{GetDhtData, ProtocolWrapper}, }; use std::sync::Arc; @@ -15,24 +14,12 @@ use std::sync::Arc; fn inner(network_state: &mut NetworkState, address: &Address) -> Result<(), HolochainError> { initialized(network_state)?; - let data = GetDhtData { + send(network_state, ProtocolWrapper::GetDht(GetDhtData { msg_id: "?".to_string(), dna_hash: network_state.dna_hash.clone().unwrap(), from_agent_id: network_state.agent_id.clone().unwrap(), address: address.to_string(), - }; - - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::GetDht(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + })) } pub fn reduce_get_entry( diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index ea44caeb00..7d7bb53a7b 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -68,6 +68,20 @@ pub fn initialized(network_state: &NetworkState) -> Result<(), HolochainError> { .ok_or(HolochainError::ErrorGeneric("Network not initialized".to_string())) } +pub fn send(network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper) -> Result<(), HolochainError> { + network_state + .network + .as_mut() + .map(|network| { + network + .lock() + .unwrap() + .send(protocol_wrapper.into()) + .map_err(|error| HolochainError::IoError(error.to_string())) + }) + .ok_or(HolochainError::ErrorGeneric("Network has to be Some because of check above".to_string()))? +} + pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, message: DirectMessage) -> Result<(), HolochainError> { let id = ProcessUniqueId::new(); @@ -79,17 +93,7 @@ pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, mes data: serde_json::from_str(&serde_json::to_string(&message).unwrap()).unwrap(), }; - let _ = network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::SendMessage(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .ok_or(HolochainError::ErrorGeneric("Network has to be Some because of check above".to_string()))?; + let _ = send(network_state, ProtocolWrapper::SendMessage(data))?; network_state .direct_message_connections diff --git a/core/src/network/reducers/publish.rs b/core/src/network/reducers/publish.rs index d5ab590591..6a353d142f 100644 --- a/core/src/network/reducers/publish.rs +++ b/core/src/network/reducers/publish.rs @@ -3,7 +3,7 @@ use crate::{ context::Context, network::{ actions::ActionResponse, - reducers::initialized, + reducers::{initialized, send}, state::NetworkState, util, }, @@ -15,7 +15,6 @@ use holochain_core_types::{ error::HolochainError, }; use holochain_net_connection::{ - net_connection::NetConnection, protocol_wrapper::{DhtData, DhtMetaData, ProtocolWrapper}, }; use std::sync::Arc; @@ -27,25 +26,13 @@ fn publish_entry( ) -> Result<(), HolochainError> { let entry_with_header = util::EntryWithHeader::from((entry.clone(), header.clone())); - let data = DhtData { + send(network_state, ProtocolWrapper::PublishDht(DhtData { msg_id: "?".to_string(), dna_hash: network_state.dna_hash.clone().unwrap(), agent_id: network_state.agent_id.clone().unwrap(), address: entry.address().to_string(), content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()).unwrap(), - }; - - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::PublishDht(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + })) } fn publish_link( @@ -65,27 +52,14 @@ fn publish_link( }; let link = link_add.link().clone(); - //let header = maybe_header.unwrap(); - let data = DhtMetaData { + send(network_state, ProtocolWrapper::PublishDhtMeta(DhtMetaData { msg_id: "?".to_string(), dna_hash: network_state.dna_hash.clone().unwrap(), agent_id: network_state.agent_id.clone().unwrap(), address: link.base().to_string(), attribute: String::from("link"), content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()).unwrap(), - }; - - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::PublishDhtMeta(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + })) } fn inner( diff --git a/core/src/network/reducers/respond_get.rs b/core/src/network/reducers/respond_get.rs index 5e9590327c..d53c7608ff 100644 --- a/core/src/network/reducers/respond_get.rs +++ b/core/src/network/reducers/respond_get.rs @@ -1,11 +1,10 @@ use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, reducers::initialized, state::NetworkState}, + network::{actions::ActionResponse, reducers::{initialized, send}, state::NetworkState}, }; use holochain_core_types::{entry::Entry, error::HolochainError}; use holochain_net_connection::{ - net_connection::NetConnection, protocol_wrapper::{DhtData, GetDhtData, ProtocolWrapper}, }; use std::sync::Arc; @@ -17,25 +16,13 @@ fn inner( ) -> Result<(), HolochainError> { initialized(network_state)?; - let data = DhtData { + send(network_state, ProtocolWrapper::GetDhtResult(DhtData { msg_id: get_dht_data.msg_id.clone(), dna_hash: network_state.dna_hash.clone().unwrap(), agent_id: get_dht_data.from_agent_id.clone(), address: get_dht_data.address.clone(), content: serde_json::from_str(&serde_json::to_string(&maybe_entry).unwrap()).unwrap(), - }; - - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(ProtocolWrapper::GetDhtResult(data).into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + })) } pub fn reduce_respond_get( diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 83a8039a07..4c9dfc9745 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -1,11 +1,10 @@ use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, direct_message::DirectMessage, reducers::initialized, state::NetworkState}, + network::{direct_message::DirectMessage, reducers::{initialized, send}, state::NetworkState}, }; use holochain_core_types::error::HolochainError; use holochain_net_connection::{ - net_connection::NetConnection, protocol_wrapper::{MessageData, ProtocolWrapper}, }; use std::sync::Arc; @@ -33,17 +32,7 @@ fn inner( ProtocolWrapper::SendMessage(data) }; - network_state - .network - .as_mut() - .map(|network| { - network - .lock() - .unwrap() - .send(protocol_object.into()) - .map_err(|error| HolochainError::IoError(error.to_string())) - }) - .expect("Network has to be Some because of check above") + send(network_state, protocol_object) } pub fn reduce_send_direct_message( @@ -55,19 +44,11 @@ pub fn reduce_send_direct_message( let (to_agent_id, direct_message, msg_id, is_response) = unwrap_to!(action => crate::action::Action::SendDirectMessage); - let result = inner( + let _ = inner( network_state, to_agent_id.to_string(), direct_message, msg_id.clone(), *is_response, ); - - network_state.actions.insert( - action_wrapper.clone(), - ActionResponse::RespondGet(match result { - Ok(_) => Ok(()), - Err(e) => Err(HolochainError::ErrorGeneric(e.to_string())), - }), - ); } From 30b6d36659f5f3685936722671f3e0540c455902 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 16:45:17 +0100 Subject: [PATCH 15/45] String key for direct_message_connections --- core/src/network/reducers/mod.rs | 4 ++-- core/src/network/state.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 7d7bb53a7b..34c8d99be0 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -83,10 +83,10 @@ pub fn send(network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper) } pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, message: DirectMessage) -> Result<(), HolochainError> { - let id = ProcessUniqueId::new(); + let id = ProcessUniqueId::new().to_string(); let data = MessageData { - msg_id: id.to_string(), + msg_id: id.clone(), dna_hash: network_state.dna_hash.clone().unwrap(), to_agent_id: to_agent_id.to_string(), from_agent_id: network_state.agent_id.clone().unwrap(), diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 52e9c2c7f7..e262666815 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -41,7 +41,7 @@ pub struct NetworkState { pub agent_id: Option, pub get_entry_results: HashMap, pub get_validation_package_results: HashMap, - pub direct_message_connections: HashMap, + pub direct_message_connections: HashMap, id: snowflake::ProcessUniqueId, } From 7f8c4541b0374fdaa3ae1b900fa9012c7a68c59d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 18:18:16 +0100 Subject: [PATCH 16/45] Handler for DirectMessage::ValidationPackage -> Action::HandleGetValidationPackage --- core/src/action.rs | 2 ++ core/src/network/handler/send.rs | 29 +++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index a2fe25c68a..9e90b0196a 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -115,6 +115,8 @@ pub enum Action { SendDirectMessage((Address, DirectMessage, String, bool)), GetValidationPackage(ChainHeader), + HandleGetValidationPackage((Address, Option)), + // ---------------- // Nucleus actions: diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index 18a4f8c35d..b601841d66 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -1,5 +1,8 @@ use crate::{ - context::Context, network::direct_message::DirectMessage, + action::{Action, ActionWrapper}, + context::Context, + instance::dispatch_action, + network::direct_message::DirectMessage, workflows::respond_validation_package_request::respond_validation_package_request, }; use holochain_core_types::cas::content::Address; @@ -41,15 +44,33 @@ pub fn handle_send(message_data: MessageData, context: Arc) { /// We got a ProtocolWrapper::SendResult, this means somebody has responded to our message /// -> we called and this is the answer pub fn handle_send_result(message_data: MessageData, context: Arc) { - let message: DirectMessage = + let response: DirectMessage = serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()).unwrap(); - match message { + let initial_message = context.state() + .unwrap() + .network() + .as_ref() + .direct_message_connections + .get(&message_data.msg_id) + .cloned(); + + match response { DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), DirectMessage::RequestValidationPackage(_) => log( &context, "Got DirectMessage::RequestValidationPackage as a response. This should not happen." ), - DirectMessage::ValidationPackage(maybe_validation_package) => {} + DirectMessage::ValidationPackage(maybe_validation_package) => { + if initial_message.is_none() { + log(&context, "Received a validation package but could not find message ID in history. Not able to process."); + return; + } + + let initial_message = initial_message.unwrap(); + let address = unwrap_to!(initial_message => DirectMessage::RequestValidationPackage); + let action_wrapper = ActionWrapper::new(Action::HandleGetValidationPackage((address.clone(), maybe_validation_package.clone()))); + dispatch_action(&context.action_channel, action_wrapper.clone()); + } } } From 6581aafb65798c51b147b3e89f7bf00c1d75c2f6 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 18:23:42 +0100 Subject: [PATCH 17/45] reduce_handle_get_validation_package --- .../reducers/handle_get_validation_package.rs | 20 +++++++++++++++++++ core/src/network/reducers/mod.rs | 1 + 2 files changed, 21 insertions(+) create mode 100644 core/src/network/reducers/handle_get_validation_package.rs diff --git a/core/src/network/reducers/handle_get_validation_package.rs b/core/src/network/reducers/handle_get_validation_package.rs new file mode 100644 index 0000000000..bbf3c2041d --- /dev/null +++ b/core/src/network/reducers/handle_get_validation_package.rs @@ -0,0 +1,20 @@ +use crate::{ + action::ActionWrapper, context::Context, + network::{ + state::NetworkState, + } +}; +use std::sync::Arc; + +pub fn reduce_handle_get_validation_package( + _context: Arc, + network_state: &mut NetworkState, + action_wrapper: &ActionWrapper, +) { + let action = action_wrapper.action(); + let (address, maybe_validation_package) = unwrap_to!(action => crate::action::Action::HandleGetValidationPackage); + + network_state + .get_validation_package_results + .insert(address.clone(), Some(Ok(maybe_validation_package.clone()))); +} diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 34c8d99be0..cd21077808 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -1,6 +1,7 @@ pub mod get_entry; pub mod get_validation_package; pub mod handle_get_result; +pub mod handle_get_validation_package; pub mod init; pub mod publish; pub mod respond_get; From 35cf961ff0ce7ecfc0b070934a47c515282ebf8b Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 18:43:15 +0100 Subject: [PATCH 18/45] Action::ResolveDirectConnection with reducer and usage --- core/src/action.rs | 2 ++ core/src/network/handler/send.rs | 4 ++++ .../reducers/resolve_direct_connection.rs | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 core/src/network/reducers/resolve_direct_connection.rs diff --git a/core/src/action.rs b/core/src/action.rs index 9e90b0196a..e95eecbc3d 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -114,6 +114,8 @@ pub enum Action { /// 4th parameter is true for a response to a previous message, false for a new interaction SendDirectMessage((Address, DirectMessage, String, bool)), + ResolveDirectConnection(String), + GetValidationPackage(ChainHeader), HandleGetValidationPackage((Address, Option)), diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index b601841d66..6e15094a12 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -69,8 +69,12 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { let initial_message = initial_message.unwrap(); let address = unwrap_to!(initial_message => DirectMessage::RequestValidationPackage); + let action_wrapper = ActionWrapper::new(Action::HandleGetValidationPackage((address.clone(), maybe_validation_package.clone()))); dispatch_action(&context.action_channel, action_wrapper.clone()); + + let action_wrapper = ActionWrapper::new(Action::ResolveDirectConnection(message_data.msg_id)); + dispatch_action(&context.action_channel, action_wrapper.clone()); } } } diff --git a/core/src/network/reducers/resolve_direct_connection.rs b/core/src/network/reducers/resolve_direct_connection.rs new file mode 100644 index 0000000000..56ff6c494f --- /dev/null +++ b/core/src/network/reducers/resolve_direct_connection.rs @@ -0,0 +1,20 @@ +use crate::{ + action::ActionWrapper, context::Context, + network::{ + state::NetworkState, + } +}; +use std::sync::Arc; + +pub fn reduce_resolve_direct_connection( + _context: Arc, + network_state: &mut NetworkState, + action_wrapper: &ActionWrapper, +) { + let action = action_wrapper.action(); + let id = unwrap_to!(action => crate::action::Action::ResolveDirectConnection); + + network_state + .direct_message_connections + .remove(id); +} From 579fbc59af121a4baea8aa6dae5e49da33be03a9 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 18:43:22 +0100 Subject: [PATCH 19/45] Action comments --- core/src/action.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/src/action.rs b/core/src/action.rs index e95eecbc3d..b94e58a15f 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -99,14 +99,29 @@ pub enum Action { // 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)), + + /// 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), GetEntryTimeout(Address), + /// 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)), + + /// 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. @@ -114,9 +129,18 @@ pub enum Action { /// 4th parameter is true for a response to a previous message, false for a new interaction SendDirectMessage((Address, DirectMessage, String, bool)), + /// 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)), From 77c6d6f16c41ef0bd05edcdc7729fb6a24a40ca6 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 19:40:32 +0100 Subject: [PATCH 20/45] Index new network reducers --- core/src/network/reducers/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index cd21077808..ff200424f6 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -4,6 +4,7 @@ pub mod handle_get_result; pub mod handle_get_validation_package; pub mod init; pub mod publish; +pub mod resolve_direct_connection; pub mod respond_get; pub mod send_direct_message; @@ -15,10 +16,14 @@ use crate::{ direct_message::DirectMessage, reducers::{ get_entry::{reduce_get_entry, reduce_get_entry_timeout}, + get_validation_package::reduce_get_validation_package, handle_get_result::reduce_handle_get_result, + handle_get_validation_package::reduce_handle_get_validation_package, init::reduce_init, publish::reduce_publish, + resolve_direct_connection::reduce_resolve_direct_connection, respond_get::reduce_respond_get, + send_direct_message::reduce_send_direct_message, }, state::NetworkState, }, @@ -39,10 +44,14 @@ fn resolve_reducer(action_wrapper: &ActionWrapper) -> Option { match action_wrapper.action() { Action::GetEntry(_) => Some(reduce_get_entry), Action::GetEntryTimeout(_) => Some(reduce_get_entry_timeout), + Action::GetValidationPackage(_) => Some(reduce_get_validation_package), Action::HandleGetResult(_) => Some(reduce_handle_get_result), + Action::HandleGetValidationPackage(_) => Some(reduce_handle_get_validation_package), Action::InitNetwork(_) => Some(reduce_init), Action::Publish(_) => Some(reduce_publish), + Action::ResolveDirectConnection(_) => Some(reduce_resolve_direct_connection), Action::RespondGet(_) => Some(reduce_respond_get), + Action::SendDirectMessage(_) => Some(reduce_send_direct_message), _ => None, } } @@ -94,6 +103,8 @@ pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, mes data: serde_json::from_str(&serde_json::to_string(&message).unwrap()).unwrap(), }; + println!("SEND MESSAGE: {:?}", data); + let _ = send(network_state, ProtocolWrapper::SendMessage(data))?; network_state From 69551784a6ab2b173f7c898ad1672dc87dd8da91 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 6 Dec 2018 19:41:06 +0100 Subject: [PATCH 21/45] test get_validation_package_roundtrip() --- core/src/network/mod.rs | 103 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/core/src/network/mod.rs b/core/src/network/mod.rs index 4921e64711..35d592c528 100644 --- a/core/src/network/mod.rs +++ b/core/src/network/mod.rs @@ -8,7 +8,12 @@ mod util; #[cfg(test)] pub mod tests { use crate::{ - instance::tests::test_instance_and_context_by_name, network::actions::get_entry::get_entry, + instance::tests::test_instance_and_context_by_name, + network::actions::{ + get_entry::get_entry, + get_validation_package::get_validation_package, + }, + workflows::author_entry::author_entry, }; use futures::executor::block_on; use holochain_core_types::{cas::content::AddressableContent, entry::test_entry}; @@ -60,4 +65,100 @@ pub mod tests { let maybe_entry = result.unwrap(); assert!(maybe_entry.is_none()); } + + + #[test] + fn get_validation_package_roundtrip() { + let wat= + r#" +(module + + (memory 1) + (export "memory" (memory 0)) + + (func + (export "__hdk_validate_app_entry") + (param $allocation i32) + (result i32) + + (i32.const 0) + ) + + (func + (export "__hdk_validate_link") + (param $allocation i32) + (result i32) + + (i32.const 0) + ) + + + (func + (export "__hdk_get_validation_package_for_entry_type") + (param $allocation i32) + (result i32) + + ;; This writes "Entry" into memory + (i32.store (i32.const 0) (i32.const 34)) + (i32.store (i32.const 1) (i32.const 69)) + (i32.store (i32.const 2) (i32.const 110)) + (i32.store (i32.const 3) (i32.const 116)) + (i32.store (i32.const 4) (i32.const 114)) + (i32.store (i32.const 5) (i32.const 121)) + (i32.store (i32.const 6) (i32.const 34)) + + (i32.const 7) + ) + + (func + (export "__hdk_get_validation_package_for_link") + (param $allocation i32) + (result i32) + + ;; This writes "Entry" into memory + (i32.store (i32.const 0) (i32.const 34)) + (i32.store (i32.const 1) (i32.const 69)) + (i32.store (i32.const 2) (i32.const 110)) + (i32.store (i32.const 3) (i32.const 116)) + (i32.store (i32.const 4) (i32.const 114)) + (i32.store (i32.const 5) (i32.const 121)) + (i32.store (i32.const 6) (i32.const 34)) + + (i32.const 7) + ) + + (func + (export "__list_capabilities") + (param $allocation i32) + (result i32) + + (i32.const 0) + ) +) + "#; + + + let mut dna = create_test_dna_with_wat("test_zome", "test_cap", Some(wat)); + dna.uuid = String::from("get_validation_package_roundtrip"); + let (_, context1) = test_instance_and_context_by_name(dna.clone(), "alice1").unwrap(); + + println!("AGENT 1 address: {}", context1.agent_id.address()); + + let entry = test_entry(); + block_on(author_entry(&entry, &context1)) + .expect("Could not author entry"); + + let agent1_state = context1.state().unwrap().agent(); + let header = agent1_state.chain() + .iter_type(&agent1_state.top_chain_header(), &entry.entry_type()) + .find(|h| h.entry_address() == &entry.address()) + .expect("There must be a header in the author's source chain after commit"); + + + let (_, context2) = test_instance_and_context_by_name(dna.clone(), "bob1").unwrap(); + let result = block_on(get_validation_package(header, &context2)); + + assert!(result.is_ok()); + println!("{:?}", result.unwrap()); + } } From 6f494af8967b5b55cbe32b4a581b28d7280e8d2b Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:22:54 +0100 Subject: [PATCH 22/45] Make sure address function of entry delegates to AgentId::address() if the entry is an AgendId entry. --- core_types/src/entry/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core_types/src/entry/mod.rs b/core_types/src/entry/mod.rs index 8461ecde37..18c0ed7bc3 100644 --- a/core_types/src/entry/mod.rs +++ b/core_types/src/entry/mod.rs @@ -13,6 +13,7 @@ use link::{link_add::LinkAdd, link_list::LinkList, link_remove::LinkRemove}; use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serializer}; use snowflake; use std::convert::TryFrom; +use multihash::Hash; pub type AppEntryValue = JsonString; @@ -98,6 +99,13 @@ impl PartialEq for Entry { } impl AddressableContent for Entry { + fn address(&self) -> Address { + match &self { + Entry::AgentId(agent_id) => agent_id.address(), + _ => Address::encode_from_str(&String::from(self.content()), Hash::SHA2256), + } + } + fn content(&self) -> Content { self.into() } From 76fa8420a9ea43014891b284ea4ece3a823f27ad Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:37:11 +0100 Subject: [PATCH 23/45] Swap ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSendResult Those were mixed up --- core/src/network/handler/mod.rs | 2 +- net/src/mock_worker.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs index 5ca0a40c8c..dc21ac0fee 100644 --- a/core/src/network/handler/mod.rs +++ b/core/src/network/handler/mod.rs @@ -28,7 +28,7 @@ pub fn create_handler(c: &Arc) -> NetHandler { Ok(ProtocolWrapper::HandleSend(message_data)) => { handle_send(message_data, context.clone()) } - Ok(ProtocolWrapper::SendResult(message_data)) => { + Ok(ProtocolWrapper::HandleSendResult(message_data)) => { handle_send_result(message_data, context.clone()) } _ => {} diff --git a/net/src/mock_worker.rs b/net/src/mock_worker.rs index 1edd4031bc..2e5354e4b5 100644 --- a/net/src/mock_worker.rs +++ b/net/src/mock_worker.rs @@ -65,7 +65,7 @@ impl MockSingleton { ProtocolWrapper::SendMessage(msg) => { self.priv_handle_send(&msg)?; } - ProtocolWrapper::HandleSendResult(msg) => { + ProtocolWrapper::SendResult(msg) => { self.priv_handle_send_result(&msg)?; } ProtocolWrapper::SuccessResult(msg) => { @@ -145,7 +145,7 @@ impl MockSingleton { self.priv_send_one( &msg.dna_hash, &msg.to_agent_id, - ProtocolWrapper::SendResult(msg.clone()).into(), + ProtocolWrapper::HandleSendResult(msg.clone()).into(), )?; Ok(()) } From c4fd511711f70961ad9de603e408c354781fc4f8 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:39:35 +0100 Subject: [PATCH 24/45] Async funciton needs polling --- core/src/network/handler/send.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index 6e15094a12..772e8246b4 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -5,8 +5,12 @@ use crate::{ network::direct_message::DirectMessage, workflows::respond_validation_package_request::respond_validation_package_request, }; +use futures::executor::block_on; use holochain_core_types::cas::content::Address; -use std::sync::Arc; +use std::{ + sync::Arc, + thread, +}; use holochain_net_connection::protocol_wrapper::MessageData; @@ -27,12 +31,18 @@ pub fn handle_send(message_data: MessageData, context: Arc) { match message { DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), DirectMessage::RequestValidationPackage(address) => { - respond_validation_package_request( - Address::from(message_data.from_agent_id), - message_data.msg_id, - address, - context.clone(), - ); + // Async functions only get executed when they are polled. + // I don't want to wait for this workflow to finish here as it would block the + // network thread, so I use block_on to poll the async function but do that in + // another thread: + thread::spawn(move || { + block_on(respond_validation_package_request( + Address::from(message_data.from_agent_id), + message_data.msg_id, + address, + context.clone(), + )); + }); } DirectMessage::ValidationPackage(_) => log( &context, From b6c9a3f6b398024532bb591a82651d6aa39436fc Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:40:18 +0100 Subject: [PATCH 25/45] Finalize test get_validation_package_roundtrip --- core/src/network/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/network/mod.rs b/core/src/network/mod.rs index 35d592c528..ce8f127a22 100644 --- a/core/src/network/mod.rs +++ b/core/src/network/mod.rs @@ -142,12 +142,10 @@ pub mod tests { dna.uuid = String::from("get_validation_package_roundtrip"); let (_, context1) = test_instance_and_context_by_name(dna.clone(), "alice1").unwrap(); - println!("AGENT 1 address: {}", context1.agent_id.address()); - let entry = test_entry(); block_on(author_entry(&entry, &context1)) .expect("Could not author entry"); - + let agent1_state = context1.state().unwrap().agent(); let header = agent1_state.chain() .iter_type(&agent1_state.top_chain_header(), &entry.entry_type()) @@ -156,9 +154,12 @@ pub mod tests { let (_, context2) = test_instance_and_context_by_name(dna.clone(), "bob1").unwrap(); - let result = block_on(get_validation_package(header, &context2)); + let result = block_on(get_validation_package(header.clone(), &context2)); assert!(result.is_ok()); - println!("{:?}", result.unwrap()); + let maybe_validation_package = result.unwrap(); + assert!(maybe_validation_package.is_some()); + let validation_package = maybe_validation_package.unwrap(); + assert_eq!(validation_package.chain_header, Some(header)); } } From f0726a7d202d2f20638da31bbfa9e7ba20431257 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:40:48 +0100 Subject: [PATCH 26/45] Debug output when send failed --- core/src/network/reducers/send_direct_message.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 4c9dfc9745..791b73bc49 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -44,11 +44,13 @@ pub fn reduce_send_direct_message( let (to_agent_id, direct_message, msg_id, is_response) = unwrap_to!(action => crate::action::Action::SendDirectMessage); - let _ = inner( + if let Err(error) = inner( network_state, to_agent_id.to_string(), direct_message, msg_id.clone(), *is_response, - ); + ) { + println!("Error sending direct message: {:?}", error); + } } From 96c486238f5a9a252554ed68590cfe0470d64cf9 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 16:56:14 +0100 Subject: [PATCH 27/45] rustfmt --- core/src/action.rs | 10 +---- .../network/actions/get_validation_package.rs | 7 +++- core/src/network/handler/send.rs | 26 ++++++------ core/src/network/mod.rs | 19 +++------ core/src/network/reducers/get_entry.rs | 24 ++++++----- .../reducers/get_validation_package.rs | 15 +++---- .../src/network/reducers/handle_get_result.rs | 8 ++-- .../reducers/handle_get_validation_package.rs | 10 ++--- core/src/network/reducers/mod.rs | 30 +++++++------ core/src/network/reducers/publish.rs | 42 +++++++++++-------- .../reducers/resolve_direct_connection.rs | 11 +---- core/src/network/reducers/respond_get.rs | 27 +++++++----- .../network/reducers/send_direct_message.rs | 10 +++-- core/src/network/state.rs | 9 ++-- core_types/src/entry/mod.rs | 2 +- 15 files changed, 122 insertions(+), 128 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index b94e58a15f..0e00907dcc 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -9,8 +9,7 @@ use crate::{ }; use holochain_core_types::{ cas::content::Address, chain_header::ChainHeader, dna::Dna, entry::Entry, - error::HolochainError, json::JsonString, - link::Link, validation::ValidationPackage, + error::HolochainError, json::JsonString, link::Link, validation::ValidationPackage, }; use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData}; use snowflake; @@ -76,16 +75,13 @@ pub enum Action { // ---------------- // Agent actions: // ---------------- - /// Writes an entry to the source chain. /// Does not validate, assumes entry is valid. Commit(Entry), - // ------------- // DHT actions: // ------------- - /// Adds an entry to the local DHT shard. /// Does not validate, assumes entry is valid. Hold(Entry), @@ -94,11 +90,9 @@ pub enum Action { /// 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. @@ -143,11 +137,9 @@ pub enum Action { /// Triggered from the network handler when we got the response. HandleGetValidationPackage((Address, Option)), - // ---------------- // Nucleus actions: // ---------------- - /// initialize an application from a Dna /// not the same as genesis /// may call genesis internally diff --git a/core/src/network/actions/get_validation_package.rs b/core/src/network/actions/get_validation_package.rs index 38d99599e2..6b54dab1cd 100644 --- a/core/src/network/actions/get_validation_package.rs +++ b/core/src/network/actions/get_validation_package.rs @@ -25,8 +25,11 @@ use std::{ /// /// Returns a future that resolves to Option (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) -> HcResult> { - let entry_address= header.entry_address().clone(); +pub async fn get_validation_package( + header: ChainHeader, + context: &Arc, +) -> HcResult> { + 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 { diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index 772e8246b4..0bd0ba1d14 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -7,19 +7,12 @@ use crate::{ }; use futures::executor::block_on; use holochain_core_types::cas::content::Address; -use std::{ - sync::Arc, - thread, -}; +use std::{sync::Arc, thread}; use holochain_net_connection::protocol_wrapper::MessageData; fn log>(context: &Arc, msg: T) { - context - .logger - .lock() - .unwrap() - .log(msg.into()); + context.logger.lock().unwrap().log(msg.into()); } /// We got a ProtocolWrapper::SendMessage, this means somebody initiates message roundtrip @@ -46,7 +39,7 @@ pub fn handle_send(message_data: MessageData, context: Arc) { } DirectMessage::ValidationPackage(_) => log( &context, - "Got DirectMessage::ValidationPackage as initial message. This should not happen." + "Got DirectMessage::ValidationPackage as initial message. This should not happen.", ), } } @@ -57,7 +50,8 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { let response: DirectMessage = serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()).unwrap(); - let initial_message = context.state() + let initial_message = context + .state() .unwrap() .network() .as_ref() @@ -69,7 +63,7 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), DirectMessage::RequestValidationPackage(_) => log( &context, - "Got DirectMessage::RequestValidationPackage as a response. This should not happen." + "Got DirectMessage::RequestValidationPackage as a response. This should not happen.", ), DirectMessage::ValidationPackage(maybe_validation_package) => { if initial_message.is_none() { @@ -80,10 +74,14 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { let initial_message = initial_message.unwrap(); let address = unwrap_to!(initial_message => DirectMessage::RequestValidationPackage); - let action_wrapper = ActionWrapper::new(Action::HandleGetValidationPackage((address.clone(), maybe_validation_package.clone()))); + let action_wrapper = ActionWrapper::new(Action::HandleGetValidationPackage(( + address.clone(), + maybe_validation_package.clone(), + ))); dispatch_action(&context.action_channel, action_wrapper.clone()); - let action_wrapper = ActionWrapper::new(Action::ResolveDirectConnection(message_data.msg_id)); + let action_wrapper = + ActionWrapper::new(Action::ResolveDirectConnection(message_data.msg_id)); dispatch_action(&context.action_channel, action_wrapper.clone()); } } diff --git a/core/src/network/mod.rs b/core/src/network/mod.rs index ce8f127a22..424c0c094c 100644 --- a/core/src/network/mod.rs +++ b/core/src/network/mod.rs @@ -9,10 +9,7 @@ mod util; pub mod tests { use crate::{ instance::tests::test_instance_and_context_by_name, - network::actions::{ - get_entry::get_entry, - get_validation_package::get_validation_package, - }, + network::actions::{get_entry::get_entry, get_validation_package::get_validation_package}, workflows::author_entry::author_entry, }; use futures::executor::block_on; @@ -66,11 +63,9 @@ pub mod tests { assert!(maybe_entry.is_none()); } - #[test] fn get_validation_package_roundtrip() { - let wat= - r#" + let wat = r#" (module (memory 1) @@ -137,22 +132,20 @@ pub mod tests { ) "#; - let mut dna = create_test_dna_with_wat("test_zome", "test_cap", Some(wat)); dna.uuid = String::from("get_validation_package_roundtrip"); let (_, context1) = test_instance_and_context_by_name(dna.clone(), "alice1").unwrap(); let entry = test_entry(); - block_on(author_entry(&entry, &context1)) - .expect("Could not author entry"); - + block_on(author_entry(&entry, &context1)).expect("Could not author entry"); + let agent1_state = context1.state().unwrap().agent(); - let header = agent1_state.chain() + let header = agent1_state + .chain() .iter_type(&agent1_state.top_chain_header(), &entry.entry_type()) .find(|h| h.entry_address() == &entry.address()) .expect("There must be a header in the author's source chain after commit"); - let (_, context2) = test_instance_and_context_by_name(dna.clone(), "bob1").unwrap(); let result = block_on(get_validation_package(header.clone(), &context2)); diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index 7e86a72318..abd599f578 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -1,25 +1,27 @@ use crate::{ - action::ActionWrapper, context::Context, + action::ActionWrapper, + context::Context, network::{ reducers::{initialized, send}, state::NetworkState, - } + }, }; use holochain_core_types::{cas::content::Address, error::HolochainError}; -use holochain_net_connection::{ - protocol_wrapper::{GetDhtData, ProtocolWrapper}, -}; +use holochain_net_connection::protocol_wrapper::{GetDhtData, ProtocolWrapper}; use std::sync::Arc; fn inner(network_state: &mut NetworkState, address: &Address) -> Result<(), HolochainError> { initialized(network_state)?; - send(network_state, ProtocolWrapper::GetDht(GetDhtData { - msg_id: "?".to_string(), - dna_hash: network_state.dna_hash.clone().unwrap(), - from_agent_id: network_state.agent_id.clone().unwrap(), - address: address.to_string(), - })) + send( + network_state, + ProtocolWrapper::GetDht(GetDhtData { + msg_id: "?".to_string(), + dna_hash: network_state.dna_hash.clone().unwrap(), + from_agent_id: network_state.agent_id.clone().unwrap(), + address: address.to_string(), + }), + ) } pub fn reduce_get_entry( diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index 289e2a25eb..8e80958cf7 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -1,21 +1,22 @@ use crate::{ - action::ActionWrapper, context::Context, + action::ActionWrapper, + context::Context, network::{ direct_message::DirectMessage, reducers::{initialized, send_message}, - state::NetworkState + state::NetworkState, }, }; -use holochain_core_types::{ - chain_header::ChainHeader, - error::HolochainError, -}; +use holochain_core_types::{chain_header::ChainHeader, error::HolochainError}; use std::sync::Arc; fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), HolochainError> { initialized(network_state)?; - let source_address = header.sources().first().expect("A header must have at least one source"); + let source_address = header + .sources() + .first() + .expect("A header must have at least one source"); let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); send_message(network_state, source_address, direct_message) diff --git a/core/src/network/reducers/handle_get_result.rs b/core/src/network/reducers/handle_get_result.rs index 1bfa13ea04..f46eaa6507 100644 --- a/core/src/network/reducers/handle_get_result.rs +++ b/core/src/network/reducers/handle_get_result.rs @@ -1,9 +1,7 @@ use crate::{ - action::ActionWrapper, context::Context, - network::{ - reducers::initialized, - state::NetworkState, - } + action::ActionWrapper, + context::Context, + network::{reducers::initialized, state::NetworkState}, }; use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; use holochain_net_connection::protocol_wrapper::DhtData; diff --git a/core/src/network/reducers/handle_get_validation_package.rs b/core/src/network/reducers/handle_get_validation_package.rs index bbf3c2041d..61972c5d27 100644 --- a/core/src/network/reducers/handle_get_validation_package.rs +++ b/core/src/network/reducers/handle_get_validation_package.rs @@ -1,9 +1,4 @@ -use crate::{ - action::ActionWrapper, context::Context, - network::{ - state::NetworkState, - } -}; +use crate::{action::ActionWrapper, context::Context, network::state::NetworkState}; use std::sync::Arc; pub fn reduce_handle_get_validation_package( @@ -12,7 +7,8 @@ pub fn reduce_handle_get_validation_package( action_wrapper: &ActionWrapper, ) { let action = action_wrapper.action(); - let (address, maybe_validation_package) = unwrap_to!(action => crate::action::Action::HandleGetValidationPackage); + let (address, maybe_validation_package) = + unwrap_to!(action => crate::action::Action::HandleGetValidationPackage); network_state .get_validation_package_results diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index ff200424f6..5a357675db 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -28,10 +28,7 @@ use crate::{ state::NetworkState, }, }; -use holochain_core_types::{ - cas::content::Address, - error::HolochainError, -}; +use holochain_core_types::{cas::content::Address, error::HolochainError}; use holochain_net_connection::{ net_connection::NetConnection, protocol_wrapper::{MessageData, ProtocolWrapper}, @@ -75,10 +72,15 @@ pub fn reduce( pub fn initialized(network_state: &NetworkState) -> Result<(), HolochainError> { (network_state.network.is_some() && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or(HolochainError::ErrorGeneric("Network not initialized".to_string())) + .ok_or(HolochainError::ErrorGeneric( + "Network not initialized".to_string(), + )) } -pub fn send(network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper) -> Result<(), HolochainError> { +pub fn send( + network_state: &mut NetworkState, + protocol_wrapper: ProtocolWrapper, +) -> Result<(), HolochainError> { network_state .network .as_mut() @@ -89,10 +91,16 @@ pub fn send(network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper) .send(protocol_wrapper.into()) .map_err(|error| HolochainError::IoError(error.to_string())) }) - .ok_or(HolochainError::ErrorGeneric("Network has to be Some because of check above".to_string()))? + .ok_or(HolochainError::ErrorGeneric( + "Network has to be Some because of check above".to_string(), + ))? } -pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, message: DirectMessage) -> Result<(), HolochainError> { +pub fn send_message( + network_state: &mut NetworkState, + to_agent_id: &Address, + message: DirectMessage, +) -> Result<(), HolochainError> { let id = ProcessUniqueId::new().to_string(); let data = MessageData { @@ -107,9 +115,7 @@ pub fn send_message(network_state: &mut NetworkState, to_agent_id: &Address, mes let _ = send(network_state, ProtocolWrapper::SendMessage(data))?; - network_state - .direct_message_connections - .insert(id, message); + network_state.direct_message_connections.insert(id, message); Ok(()) -} \ No newline at end of file +} diff --git a/core/src/network/reducers/publish.rs b/core/src/network/reducers/publish.rs index 6a353d142f..45895d70aa 100644 --- a/core/src/network/reducers/publish.rs +++ b/core/src/network/reducers/publish.rs @@ -14,9 +14,7 @@ use holochain_core_types::{ entry::{entry_type::EntryType, Entry}, error::HolochainError, }; -use holochain_net_connection::{ - protocol_wrapper::{DhtData, DhtMetaData, ProtocolWrapper}, -}; +use holochain_net_connection::protocol_wrapper::{DhtData, DhtMetaData, ProtocolWrapper}; use std::sync::Arc; fn publish_entry( @@ -26,13 +24,17 @@ fn publish_entry( ) -> Result<(), HolochainError> { let entry_with_header = util::EntryWithHeader::from((entry.clone(), header.clone())); - send(network_state, ProtocolWrapper::PublishDht(DhtData { - msg_id: "?".to_string(), - dna_hash: network_state.dna_hash.clone().unwrap(), - agent_id: network_state.agent_id.clone().unwrap(), - address: entry.address().to_string(), - content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()).unwrap(), - })) + send( + network_state, + ProtocolWrapper::PublishDht(DhtData { + msg_id: "?".to_string(), + dna_hash: network_state.dna_hash.clone().unwrap(), + agent_id: network_state.agent_id.clone().unwrap(), + address: entry.address().to_string(), + content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()) + .unwrap(), + }), + ) } fn publish_link( @@ -52,14 +54,18 @@ fn publish_link( }; let link = link_add.link().clone(); - send(network_state, ProtocolWrapper::PublishDhtMeta(DhtMetaData { - msg_id: "?".to_string(), - dna_hash: network_state.dna_hash.clone().unwrap(), - agent_id: network_state.agent_id.clone().unwrap(), - address: link.base().to_string(), - attribute: String::from("link"), - content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()).unwrap(), - })) + send( + network_state, + ProtocolWrapper::PublishDhtMeta(DhtMetaData { + msg_id: "?".to_string(), + dna_hash: network_state.dna_hash.clone().unwrap(), + agent_id: network_state.agent_id.clone().unwrap(), + address: link.base().to_string(), + attribute: String::from("link"), + content: serde_json::from_str(&serde_json::to_string(&entry_with_header).unwrap()) + .unwrap(), + }), + ) } fn inner( diff --git a/core/src/network/reducers/resolve_direct_connection.rs b/core/src/network/reducers/resolve_direct_connection.rs index 56ff6c494f..4ca993968e 100644 --- a/core/src/network/reducers/resolve_direct_connection.rs +++ b/core/src/network/reducers/resolve_direct_connection.rs @@ -1,9 +1,4 @@ -use crate::{ - action::ActionWrapper, context::Context, - network::{ - state::NetworkState, - } -}; +use crate::{action::ActionWrapper, context::Context, network::state::NetworkState}; use std::sync::Arc; pub fn reduce_resolve_direct_connection( @@ -14,7 +9,5 @@ pub fn reduce_resolve_direct_connection( let action = action_wrapper.action(); let id = unwrap_to!(action => crate::action::Action::ResolveDirectConnection); - network_state - .direct_message_connections - .remove(id); + network_state.direct_message_connections.remove(id); } diff --git a/core/src/network/reducers/respond_get.rs b/core/src/network/reducers/respond_get.rs index d53c7608ff..d3490402ce 100644 --- a/core/src/network/reducers/respond_get.rs +++ b/core/src/network/reducers/respond_get.rs @@ -1,12 +1,14 @@ use crate::{ action::ActionWrapper, context::Context, - network::{actions::ActionResponse, reducers::{initialized, send}, state::NetworkState}, + network::{ + actions::ActionResponse, + reducers::{initialized, send}, + state::NetworkState, + }, }; use holochain_core_types::{entry::Entry, error::HolochainError}; -use holochain_net_connection::{ - protocol_wrapper::{DhtData, GetDhtData, ProtocolWrapper}, -}; +use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData, ProtocolWrapper}; use std::sync::Arc; fn inner( @@ -16,13 +18,16 @@ fn inner( ) -> Result<(), HolochainError> { initialized(network_state)?; - send(network_state, ProtocolWrapper::GetDhtResult(DhtData { - msg_id: get_dht_data.msg_id.clone(), - dna_hash: network_state.dna_hash.clone().unwrap(), - agent_id: get_dht_data.from_agent_id.clone(), - address: get_dht_data.address.clone(), - content: serde_json::from_str(&serde_json::to_string(&maybe_entry).unwrap()).unwrap(), - })) + send( + network_state, + ProtocolWrapper::GetDhtResult(DhtData { + msg_id: get_dht_data.msg_id.clone(), + dna_hash: network_state.dna_hash.clone().unwrap(), + agent_id: get_dht_data.from_agent_id.clone(), + address: get_dht_data.address.clone(), + content: serde_json::from_str(&serde_json::to_string(&maybe_entry).unwrap()).unwrap(), + }), + ) } pub fn reduce_respond_get( diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 791b73bc49..1bd6a2a0c6 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -1,12 +1,14 @@ use crate::{ action::ActionWrapper, context::Context, - network::{direct_message::DirectMessage, reducers::{initialized, send}, state::NetworkState}, + network::{ + direct_message::DirectMessage, + reducers::{initialized, send}, + state::NetworkState, + }, }; use holochain_core_types::error::HolochainError; -use holochain_net_connection::{ - protocol_wrapper::{MessageData, ProtocolWrapper}, -}; +use holochain_net_connection::protocol_wrapper::{MessageData, ProtocolWrapper}; use std::sync::Arc; fn inner( diff --git a/core/src/network/state.rs b/core/src/network/state.rs index e262666815..3c8f196213 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -1,11 +1,10 @@ use crate::{ action::ActionWrapper, - network::{ - actions::ActionResponse, - direct_message::DirectMessage, - } + network::{actions::ActionResponse, direct_message::DirectMessage}, +}; +use holochain_core_types::{ + cas::content::Address, entry::Entry, error::HolochainError, validation::ValidationPackage, }; -use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError, validation::ValidationPackage}; use holochain_net::p2p_network::P2pNetwork; use snowflake; use std::{ diff --git a/core_types/src/entry/mod.rs b/core_types/src/entry/mod.rs index 18c0ed7bc3..bc2d22a64f 100644 --- a/core_types/src/entry/mod.rs +++ b/core_types/src/entry/mod.rs @@ -10,10 +10,10 @@ use entry::entry_type::{test_app_entry_type, test_app_entry_type_b, AppEntryType use error::{HcResult, HolochainError}; use json::{default_to_json, default_try_from_json, JsonString, RawString}; use link::{link_add::LinkAdd, link_list::LinkList, link_remove::LinkRemove}; +use multihash::Hash; use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serializer}; use snowflake; use std::convert::TryFrom; -use multihash::Hash; pub type AppEntryValue = JsonString; From b66068a7129db1e4013d50302f88dd3c937407ac Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 17:31:24 +0100 Subject: [PATCH 28/45] Change test fixture to expect real fake agent address --- hdk-rust/tests/integration_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hdk-rust/tests/integration_test.rs b/hdk-rust/tests/integration_test.rs index c2c7178c92..0f1d8c4af3 100644 --- a/hdk-rust/tests/integration_test.rs +++ b/hdk-rust/tests/integration_test.rs @@ -173,7 +173,7 @@ fn can_use_globals() { assert_eq!( result.clone(), Ok(JsonString::from(HashString::from( - "QmfFVhScc1cVzEqTBVLBr6d2FbsHaM5Cn3ynnvM7CUiJp9" + "alex--------------------------------------------------------------------------------ADO_" ))), "result = {:?}", result From e812ae798223730d94c709fe83bdb8b1f59db04f Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 17:31:55 +0100 Subject: [PATCH 29/45] Adjust MockWorker's test for swap SendResult <> HandleSendResult --- net/src/mock_worker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/src/mock_worker.rs b/net/src/mock_worker.rs index 2e5354e4b5..f7fbef7993 100644 --- a/net/src/mock_worker.rs +++ b/net/src/mock_worker.rs @@ -389,7 +389,7 @@ mod tests { if let ProtocolWrapper::HandleSend(msg) = res { cli2.receive( - ProtocolWrapper::HandleSendResult(MessageData { + ProtocolWrapper::SendResult(MessageData { dna_hash: msg.dna_hash, to_agent_id: msg.from_agent_id, from_agent_id: AGENT_ID_2.to_string(), @@ -407,7 +407,7 @@ mod tests { let res = ProtocolWrapper::try_from(handler_recv_1.recv().unwrap()).unwrap(); - if let ProtocolWrapper::SendResult(msg) = res { + if let ProtocolWrapper::HandleSendResult(msg) = res { assert_eq!("\"echo: \\\"hello\\\"\"".to_string(), msg.data.to_string()); } else { panic!("bad msg"); From 9d3efe50bdc0dc9806de82309a5ef81c8da17ef2 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:17:42 +0100 Subject: [PATCH 30/45] Move initialized() into NetworkState --- core/src/network/reducers/get_entry.rs | 4 ++-- core/src/network/reducers/get_validation_package.rs | 4 ++-- core/src/network/reducers/handle_get_result.rs | 4 ++-- core/src/network/reducers/mod.rs | 9 --------- core/src/network/reducers/publish.rs | 4 ++-- core/src/network/reducers/respond_get.rs | 4 ++-- core/src/network/reducers/send_direct_message.rs | 4 ++-- core/src/network/state.rs | 9 +++++++++ 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index abd599f578..ad58a96039 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -2,7 +2,7 @@ use crate::{ action::ActionWrapper, context::Context, network::{ - reducers::{initialized, send}, + reducers::send, state::NetworkState, }, }; @@ -11,7 +11,7 @@ use holochain_net_connection::protocol_wrapper::{GetDhtData, ProtocolWrapper}; use std::sync::Arc; fn inner(network_state: &mut NetworkState, address: &Address) -> Result<(), HolochainError> { - initialized(network_state)?; + network_state.initialized()?; send( network_state, diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index 8e80958cf7..a8d20ecb63 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -3,7 +3,7 @@ use crate::{ context::Context, network::{ direct_message::DirectMessage, - reducers::{initialized, send_message}, + reducers::send_message, state::NetworkState, }, }; @@ -11,7 +11,7 @@ use holochain_core_types::{chain_header::ChainHeader, error::HolochainError}; use std::sync::Arc; fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), HolochainError> { - initialized(network_state)?; + network_state.initialized()?; let source_address = header .sources() diff --git a/core/src/network/reducers/handle_get_result.rs b/core/src/network/reducers/handle_get_result.rs index f46eaa6507..59a39c212b 100644 --- a/core/src/network/reducers/handle_get_result.rs +++ b/core/src/network/reducers/handle_get_result.rs @@ -1,7 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{reducers::initialized, state::NetworkState}, + network::state::NetworkState, }; use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; use holochain_net_connection::protocol_wrapper::DhtData; @@ -11,7 +11,7 @@ fn inner( network_state: &mut NetworkState, dht_data: &DhtData, ) -> Result, HolochainError> { - initialized(network_state)?; + network_state.initialized()?; let entry: Option = serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap())?; diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 5a357675db..197b0e2af2 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -8,7 +8,6 @@ pub mod resolve_direct_connection; pub mod respond_get; pub mod send_direct_message; -use boolinator::*; use crate::{ action::{Action, ActionWrapper, NetworkReduceFn}, context::Context, @@ -69,14 +68,6 @@ pub fn reduce( } } -pub fn initialized(network_state: &NetworkState) -> Result<(), HolochainError> { - (network_state.network.is_some() - && network_state.dna_hash.is_some() & network_state.agent_id.is_some()) - .ok_or(HolochainError::ErrorGeneric( - "Network not initialized".to_string(), - )) -} - pub fn send( network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper, diff --git a/core/src/network/reducers/publish.rs b/core/src/network/reducers/publish.rs index 45895d70aa..517863fa69 100644 --- a/core/src/network/reducers/publish.rs +++ b/core/src/network/reducers/publish.rs @@ -3,7 +3,7 @@ use crate::{ context::Context, network::{ actions::ActionResponse, - reducers::{initialized, send}, + reducers::send, state::NetworkState, util, }, @@ -73,7 +73,7 @@ fn inner( network_state: &mut NetworkState, address: &Address, ) -> Result<(), HolochainError> { - initialized(network_state)?; + network_state.initialized()?; let (entry, header) = util::entry_with_header(&address, &context)?; diff --git a/core/src/network/reducers/respond_get.rs b/core/src/network/reducers/respond_get.rs index d3490402ce..3e1587f411 100644 --- a/core/src/network/reducers/respond_get.rs +++ b/core/src/network/reducers/respond_get.rs @@ -3,7 +3,7 @@ use crate::{ context::Context, network::{ actions::ActionResponse, - reducers::{initialized, send}, + reducers::send, state::NetworkState, }, }; @@ -16,7 +16,7 @@ fn inner( get_dht_data: &GetDhtData, maybe_entry: &Option, ) -> Result<(), HolochainError> { - initialized(network_state)?; + network_state.initialized()?; send( network_state, diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 1bd6a2a0c6..319bf43841 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -3,7 +3,7 @@ use crate::{ context::Context, network::{ direct_message::DirectMessage, - reducers::{initialized, send}, + reducers::send, state::NetworkState, }, }; @@ -18,7 +18,7 @@ fn inner( msg_id: String, is_response: bool, ) -> Result<(), HolochainError> { - initialized(network_state)?; + network_state.initialized()?; let data = MessageData { msg_id, diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 3c8f196213..a98764130f 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -1,3 +1,4 @@ +use boolinator::*; use crate::{ action::ActionWrapper, network::{actions::ActionResponse, direct_message::DirectMessage}, @@ -67,4 +68,12 @@ impl NetworkState { pub fn actions(&self) -> Actions { self.actions.clone() } + + pub fn initialized(&self) -> Result<(), HolochainError> { + (self.network.is_some() + && self.dna_hash.is_some() & self.agent_id.is_some()) + .ok_or(HolochainError::ErrorGeneric( + "Network not initialized".to_string(), + )) + } } From 1aa4ab79bcb44b24a289bd68230e2ad9cf900c3a Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:20:55 +0100 Subject: [PATCH 31/45] Reuse NetworkState::initialized() in action creators --- core/src/network/actions/get_entry.rs | 8 +++----- core/src/network/actions/get_validation_package.rs | 8 +++----- core/src/network/actions/publish.rs | 8 +++----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/core/src/network/actions/get_entry.rs b/core/src/network/actions/get_entry.rs index c534b0f15e..81e0ce635d 100644 --- a/core/src/network/actions/get_entry.rs +++ b/core/src/network/actions/get_entry.rs @@ -11,7 +11,7 @@ use futures::{ use holochain_core_types::{ cas::content::Address, entry::Entry, - error::{HcResult, HolochainError}, + error::HcResult, }; use std::{ pin::{Pin, Unpin}, @@ -53,10 +53,8 @@ impl Future for GetEntryFuture { fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { 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 diff --git a/core/src/network/actions/get_validation_package.rs b/core/src/network/actions/get_validation_package.rs index 6b54dab1cd..57d49109f4 100644 --- a/core/src/network/actions/get_validation_package.rs +++ b/core/src/network/actions/get_validation_package.rs @@ -11,7 +11,7 @@ use futures::{ use holochain_core_types::{ cas::content::Address, chain_header::ChainHeader, - error::{HcResult, HolochainError}, + error::HcResult, validation::ValidationPackage, }; use std::{ @@ -52,10 +52,8 @@ impl Future for GetValidationPackageFuture { fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { 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 diff --git a/core/src/network/actions/publish.rs b/core/src/network/actions/publish.rs index 69dde38566..2fd3f48076 100644 --- a/core/src/network/actions/publish.rs +++ b/core/src/network/actions/publish.rs @@ -11,7 +11,7 @@ use futures::{ }; use holochain_core_types::{ cas::content::Address, - error::{HcResult, HolochainError}, + error::HcResult, }; use std::{ pin::{Pin, Unpin}, @@ -46,10 +46,8 @@ impl Future for PublishFuture { fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { 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 From 728de2d36caba522728d0a34d479cc9d2a5b0220 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:22:15 +0100 Subject: [PATCH 32/45] rustfmt --- core/src/action.rs | 2 ++ core/src/network/actions/get_entry.rs | 6 +----- core/src/network/actions/get_validation_package.rs | 4 +--- core/src/network/actions/publish.rs | 5 +---- core/src/network/reducers/get_entry.rs | 5 +---- core/src/network/reducers/get_validation_package.rs | 6 +----- core/src/network/reducers/handle_get_result.rs | 6 +----- core/src/network/reducers/publish.rs | 7 +------ core/src/network/reducers/respond_get.rs | 6 +----- core/src/network/reducers/send_direct_message.rs | 6 +----- core/src/network/state.rs | 8 +++----- 11 files changed, 14 insertions(+), 47 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index 0e00907dcc..536675e45b 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -180,6 +180,8 @@ pub type NetworkReduceFn = ReduceFn; pub type NucleusReduceFn = ReduceFn; pub type ReduceFn = fn(Arc, &mut S, &ActionWrapper); + + #[cfg(test)] pub mod tests { diff --git a/core/src/network/actions/get_entry.rs b/core/src/network/actions/get_entry.rs index 81e0ce635d..7f2399e8f8 100644 --- a/core/src/network/actions/get_entry.rs +++ b/core/src/network/actions/get_entry.rs @@ -8,11 +8,7 @@ use futures::{ future::Future, task::{LocalWaker, Poll}, }; -use holochain_core_types::{ - cas::content::Address, - entry::Entry, - error::HcResult, -}; +use holochain_core_types::{cas::content::Address, entry::Entry, error::HcResult}; use std::{ pin::{Pin, Unpin}, sync::Arc, diff --git a/core/src/network/actions/get_validation_package.rs b/core/src/network/actions/get_validation_package.rs index 57d49109f4..e029c6bc4b 100644 --- a/core/src/network/actions/get_validation_package.rs +++ b/core/src/network/actions/get_validation_package.rs @@ -9,9 +9,7 @@ use futures::{ task::{LocalWaker, Poll}, }; use holochain_core_types::{ - cas::content::Address, - chain_header::ChainHeader, - error::HcResult, + cas::content::Address, chain_header::ChainHeader, error::HcResult, validation::ValidationPackage, }; use std::{ diff --git a/core/src/network/actions/publish.rs b/core/src/network/actions/publish.rs index 2fd3f48076..c193208372 100644 --- a/core/src/network/actions/publish.rs +++ b/core/src/network/actions/publish.rs @@ -9,10 +9,7 @@ use futures::{ future::Future, task::{LocalWaker, Poll}, }; -use holochain_core_types::{ - cas::content::Address, - error::HcResult, -}; +use holochain_core_types::{cas::content::Address, error::HcResult}; use std::{ pin::{Pin, Unpin}, sync::Arc, diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index ad58a96039..bae798e37f 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -1,10 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{ - reducers::send, - state::NetworkState, - }, + network::{reducers::send, state::NetworkState}, }; use holochain_core_types::{cas::content::Address, error::HolochainError}; use holochain_net_connection::protocol_wrapper::{GetDhtData, ProtocolWrapper}; diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index a8d20ecb63..e67a891898 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -1,11 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{ - direct_message::DirectMessage, - reducers::send_message, - state::NetworkState, - }, + network::{direct_message::DirectMessage, reducers::send_message, state::NetworkState}, }; use holochain_core_types::{chain_header::ChainHeader, error::HolochainError}; use std::sync::Arc; diff --git a/core/src/network/reducers/handle_get_result.rs b/core/src/network/reducers/handle_get_result.rs index 59a39c212b..8f5a7511b2 100644 --- a/core/src/network/reducers/handle_get_result.rs +++ b/core/src/network/reducers/handle_get_result.rs @@ -1,8 +1,4 @@ -use crate::{ - action::ActionWrapper, - context::Context, - network::state::NetworkState, -}; +use crate::{action::ActionWrapper, context::Context, network::state::NetworkState}; use holochain_core_types::{cas::content::Address, entry::Entry, error::HolochainError}; use holochain_net_connection::protocol_wrapper::DhtData; use std::sync::Arc; diff --git a/core/src/network/reducers/publish.rs b/core/src/network/reducers/publish.rs index 517863fa69..aeb2a28702 100644 --- a/core/src/network/reducers/publish.rs +++ b/core/src/network/reducers/publish.rs @@ -1,12 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{ - actions::ActionResponse, - reducers::send, - state::NetworkState, - util, - }, + network::{actions::ActionResponse, reducers::send, state::NetworkState, util}, }; use holochain_core_types::{ cas::content::{Address, AddressableContent}, diff --git a/core/src/network/reducers/respond_get.rs b/core/src/network/reducers/respond_get.rs index 3e1587f411..f186ba7bba 100644 --- a/core/src/network/reducers/respond_get.rs +++ b/core/src/network/reducers/respond_get.rs @@ -1,11 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{ - actions::ActionResponse, - reducers::send, - state::NetworkState, - }, + network::{actions::ActionResponse, reducers::send, state::NetworkState}, }; use holochain_core_types::{entry::Entry, error::HolochainError}; use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData, ProtocolWrapper}; diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 319bf43841..2cb384be96 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -1,11 +1,7 @@ use crate::{ action::ActionWrapper, context::Context, - network::{ - direct_message::DirectMessage, - reducers::send, - state::NetworkState, - }, + network::{direct_message::DirectMessage, reducers::send, state::NetworkState}, }; use holochain_core_types::error::HolochainError; use holochain_net_connection::protocol_wrapper::{MessageData, ProtocolWrapper}; diff --git a/core/src/network/state.rs b/core/src/network/state.rs index a98764130f..3a89d348f7 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -70,10 +70,8 @@ impl NetworkState { } pub fn initialized(&self) -> Result<(), HolochainError> { - (self.network.is_some() - && self.dna_hash.is_some() & self.agent_id.is_some()) - .ok_or(HolochainError::ErrorGeneric( - "Network not initialized".to_string(), - )) + (self.network.is_some() && self.dna_hash.is_some() & self.agent_id.is_some()).ok_or( + HolochainError::ErrorGeneric("Network not initialized".to_string()), + ) } } From c1e226ee87e811ef4edebe21bef239bfcdfd8c31 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:30:34 +0100 Subject: [PATCH 33/45] DirectMessageData instead of tuple --- core/src/action.rs | 10 +++++-- .../network/reducers/send_direct_message.rs | 29 ++++++------------- .../respond_validation_package_request.rs | 13 +++++---- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index 536675e45b..2af4b3fa69 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -121,7 +121,7 @@ pub enum Action { /// Sends a direct message object to the given address. /// 3rd parameter is the message id /// 4th parameter is true for a response to a previous message, false for a new interaction - SendDirectMessage((Address, DirectMessage, String, bool)), + SendDirectMessage(DirectMessageData), /// Makes the network module forget about the direct message /// connection with the given ID. @@ -180,7 +180,13 @@ pub type NetworkReduceFn = ReduceFn; pub type NucleusReduceFn = ReduceFn; pub type ReduceFn = fn(Arc, &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 { diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 2cb384be96..8e37b00dc0 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -1,7 +1,7 @@ use crate::{ - action::ActionWrapper, + action::{ActionWrapper, DirectMessageData}, context::Context, - network::{direct_message::DirectMessage, reducers::send, state::NetworkState}, + network::{reducers::send, state::NetworkState}, }; use holochain_core_types::error::HolochainError; use holochain_net_connection::protocol_wrapper::{MessageData, ProtocolWrapper}; @@ -9,22 +9,19 @@ use std::sync::Arc; fn inner( network_state: &mut NetworkState, - to_agent_id: String, - direct_message: &DirectMessage, - msg_id: String, - is_response: bool, + direct_message_data: &DirectMessageData, ) -> Result<(), HolochainError> { network_state.initialized()?; let data = MessageData { - msg_id, + msg_id: direct_message_data.msg_id.clone(), dna_hash: network_state.dna_hash.clone().unwrap(), - to_agent_id, + to_agent_id: direct_message_data.address.to_string(), from_agent_id: network_state.agent_id.clone().unwrap(), - data: serde_json::from_str(&serde_json::to_string(direct_message).unwrap()).unwrap(), + data: serde_json::from_str(&serde_json::to_string(&direct_message_data.message).unwrap()).unwrap(), }; - let protocol_object = if is_response { + let protocol_object = if direct_message_data.is_response { ProtocolWrapper::SendResult(data) } else { ProtocolWrapper::SendMessage(data) @@ -39,16 +36,8 @@ pub fn reduce_send_direct_message( action_wrapper: &ActionWrapper, ) { let action = action_wrapper.action(); - let (to_agent_id, direct_message, msg_id, is_response) = - unwrap_to!(action => crate::action::Action::SendDirectMessage); - - if let Err(error) = inner( - network_state, - to_agent_id.to_string(), - direct_message, - msg_id.clone(), - *is_response, - ) { + let dm_data = unwrap_to!(action => crate::action::Action::SendDirectMessage); + if let Err(error) = inner(network_state, dm_data) { println!("Error sending direct message: {:?}", error); } } diff --git a/core/src/workflows/respond_validation_package_request.rs b/core/src/workflows/respond_validation_package_request.rs index 2f81d56618..a87e30b474 100644 --- a/core/src/workflows/respond_validation_package_request.rs +++ b/core/src/workflows/respond_validation_package_request.rs @@ -1,5 +1,5 @@ use crate::{ - action::{Action, ActionWrapper}, + action::{Action, ActionWrapper, DirectMessageData}, context::Context, instance::dispatch_action, network::direct_message::DirectMessage, @@ -36,11 +36,12 @@ pub async fn respond_validation_package_request( }; let direct_message = DirectMessage::ValidationPackage(maybe_validation_package); - let action_wrapper = ActionWrapper::new(Action::SendDirectMessage(( - to_agent_id, - direct_message, + let direct_message_data = DirectMessageData { + address: to_agent_id, + message: direct_message, msg_id, - true, - ))); + is_response: true, + }; + let action_wrapper = ActionWrapper::new(Action::SendDirectMessage(direct_message_data)); dispatch_action(&context.action_channel, action_wrapper); } From 7f487280a537215fe534a6c6c46998afe5827315 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:50:09 +0100 Subject: [PATCH 34/45] Rustdoc comments --- core/src/network/actions/get_validation_package.rs | 5 +++-- core/src/network/actions/initialize_network.rs | 2 +- core/src/network/handler/get.rs | 3 +++ core/src/network/handler/mod.rs | 3 +++ core/src/network/handler/store.rs | 3 +++ core/src/network/reducers/mod.rs | 8 +++++++- core/src/network/state.rs | 10 ++++++++++ 7 files changed, 30 insertions(+), 4 deletions(-) diff --git a/core/src/network/actions/get_validation_package.rs b/core/src/network/actions/get_validation_package.rs index e029c6bc4b..4408cdf02c 100644 --- a/core/src/network/actions/get_validation_package.rs +++ b/core/src/network/actions/get_validation_package.rs @@ -36,8 +36,9 @@ pub async fn get_validation_package( }) } -/// PublishFuture resolves to ActionResponse -/// Tracks the state for a response to its ActionWrapper +/// GetValidationPackageFuture resolves to an Option +/// which would be None if the source responded with None, indicating that it +/// is not the source. pub struct GetValidationPackageFuture { context: Arc, address: Address, diff --git a/core/src/network/actions/initialize_network.rs b/core/src/network/actions/initialize_network.rs index a609d5415b..9846f47c75 100644 --- a/core/src/network/actions/initialize_network.rs +++ b/core/src/network/actions/initialize_network.rs @@ -31,7 +31,7 @@ async fn get_dna_and_agent(context: &Arc) -> 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) -> Result<(), HolochainError> { let (dna_hash, agent_id) = await!(get_dna_and_agent(context))?; let action_wrapper = ActionWrapper::new(Action::InitNetwork(( diff --git a/core/src/network/handler/get.rs b/core/src/network/handler/get.rs index ccff6e07c2..694172f3ad 100644 --- a/core/src/network/handler/get.rs +++ b/core/src/network/handler/get.rs @@ -10,6 +10,8 @@ use std::sync::Arc; use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData}; +/// The network has requested a DHT entry from us. +/// Lets try to get it and trigger a response. pub fn handle_get_dht(get_dht_data: GetDhtData, context: Arc) { let _ = block_on(nucleus::actions::get_entry::get_entry( &context, @@ -21,6 +23,7 @@ pub fn handle_get_dht(get_dht_data: GetDhtData, context: Arc) { }); } +/// The network comes back with a result to our previous GET request. pub fn handle_get_dht_result(dht_data: DhtData, context: Arc) { let action_wrapper = ActionWrapper::new(Action::HandleGetResult(dht_data)); dispatch_action(&context.action_channel, action_wrapper.clone()); diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs index dc21ac0fee..aa63b6bceb 100644 --- a/core/src/network/handler/mod.rs +++ b/core/src/network/handler/mod.rs @@ -9,6 +9,9 @@ use crate::{ use holochain_net_connection::{net_connection::NetHandler, protocol_wrapper::ProtocolWrapper}; use std::{convert::TryFrom, sync::Arc}; +/// Creates the network handler. +/// The returned closure is called by the network thread for every network event that core +/// has to handle. pub fn create_handler(c: &Arc) -> NetHandler { let context = c.clone(); Box::new(move |message| { diff --git a/core/src/network/handler/store.rs b/core/src/network/handler/store.rs index db3a8e4484..c11b719489 100644 --- a/core/src/network/handler/store.rs +++ b/core/src/network/handler/store.rs @@ -8,12 +8,15 @@ use holochain_core_types::entry::Entry; use holochain_net_connection::protocol_wrapper::{DhtData, DhtMetaData}; use std::sync::Arc; +/// The network requests us to store (i.e. hold) the given entry. pub fn handle_store_dht(dht_data: DhtData, context: Arc) { let entry_with_header: EntryWithHeader = serde_json::from_str(&serde_json::to_string(&dht_data.content).unwrap()).unwrap(); let _ = block_on(hold_entry(&entry_with_header.entry, &context.clone())); } +/// The network requests us to store meta information (links/CRUD/etc) for an +/// entry that we hold. pub fn handle_store_dht_meta(dht_meta_data: DhtMetaData, context: Arc) { let entry_with_header: EntryWithHeader = serde_json::from_str(&serde_json::to_string(&dht_meta_data.content).unwrap()).unwrap(); diff --git a/core/src/network/reducers/mod.rs b/core/src/network/reducers/mod.rs index 197b0e2af2..80545e2fb2 100644 --- a/core/src/network/reducers/mod.rs +++ b/core/src/network/reducers/mod.rs @@ -68,6 +68,8 @@ pub fn reduce( } } +/// Sends the given ProtocolWrapper over the network using the network proxy instance +/// that lives in the NetworkState. pub fn send( network_state: &mut NetworkState, protocol_wrapper: ProtocolWrapper, @@ -83,10 +85,14 @@ pub fn send( .map_err(|error| HolochainError::IoError(error.to_string())) }) .ok_or(HolochainError::ErrorGeneric( - "Network has to be Some because of check above".to_string(), + "Network not intialized".to_string(), ))? } +/// Sends the given DirectMessage to the node given by to_agent_id. +/// This creates a transient connection as every node-to-node communication follows a +/// request-response pattern. This function therefore logs the open connection +/// (expecting a response) in network_state.direct_message_connections. pub fn send_message( network_state: &mut NetworkState, to_agent_id: &Address, diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 3a89d348f7..11a7bbeedd 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -39,9 +39,19 @@ pub struct NetworkState { pub network: Option>>, pub dna_hash: Option, pub agent_id: Option, + + /// Here we store the results of GET entry processes. + /// None means that we are still waiting for a result from the network. pub get_entry_results: HashMap, + + /// Here we store the results of get validation package processes. + /// None means that we are still waiting for a result from the network. pub get_validation_package_results: HashMap, + + /// This stores every open (= waiting for response) node-to-node messages. + /// Entries get removed when we receive an answer through Action::ResolveDirectConnection. pub direct_message_connections: HashMap, + id: snowflake::ProcessUniqueId, } From 5e262ac71e8e1268621382e028daaacc9bf3cf6c Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:51:02 +0100 Subject: [PATCH 35/45] Revert "Swap ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSendResult" This reverts commit 76fa8420a9ea43014891b284ea4ece3a823f27ad. --- core/src/network/handler/mod.rs | 2 +- net/src/mock_worker.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/network/handler/mod.rs b/core/src/network/handler/mod.rs index aa63b6bceb..53aa726555 100644 --- a/core/src/network/handler/mod.rs +++ b/core/src/network/handler/mod.rs @@ -31,7 +31,7 @@ pub fn create_handler(c: &Arc) -> NetHandler { Ok(ProtocolWrapper::HandleSend(message_data)) => { handle_send(message_data, context.clone()) } - Ok(ProtocolWrapper::HandleSendResult(message_data)) => { + Ok(ProtocolWrapper::SendResult(message_data)) => { handle_send_result(message_data, context.clone()) } _ => {} diff --git a/net/src/mock_worker.rs b/net/src/mock_worker.rs index f7fbef7993..1a9993acd0 100644 --- a/net/src/mock_worker.rs +++ b/net/src/mock_worker.rs @@ -65,7 +65,7 @@ impl MockSingleton { ProtocolWrapper::SendMessage(msg) => { self.priv_handle_send(&msg)?; } - ProtocolWrapper::SendResult(msg) => { + ProtocolWrapper::HandleSendResult(msg) => { self.priv_handle_send_result(&msg)?; } ProtocolWrapper::SuccessResult(msg) => { @@ -145,7 +145,7 @@ impl MockSingleton { self.priv_send_one( &msg.dna_hash, &msg.to_agent_id, - ProtocolWrapper::HandleSendResult(msg.clone()).into(), + ProtocolWrapper::SendResult(msg.clone()).into(), )?; Ok(()) } From 7b020ee0b19283c64702baf63693da36b8b168c9 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 19:51:24 +0100 Subject: [PATCH 36/45] Revert "Adjust MockWorker's test for swap SendResult <> HandleSendResult" This reverts commit e812ae798223730d94c709fe83bdb8b1f59db04f. --- net/src/mock_worker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/src/mock_worker.rs b/net/src/mock_worker.rs index 1a9993acd0..1edd4031bc 100644 --- a/net/src/mock_worker.rs +++ b/net/src/mock_worker.rs @@ -389,7 +389,7 @@ mod tests { if let ProtocolWrapper::HandleSend(msg) = res { cli2.receive( - ProtocolWrapper::SendResult(MessageData { + ProtocolWrapper::HandleSendResult(MessageData { dna_hash: msg.dna_hash, to_agent_id: msg.from_agent_id, from_agent_id: AGENT_ID_2.to_string(), @@ -407,7 +407,7 @@ mod tests { let res = ProtocolWrapper::try_from(handler_recv_1.recv().unwrap()).unwrap(); - if let ProtocolWrapper::HandleSendResult(msg) = res { + if let ProtocolWrapper::SendResult(msg) = res { assert_eq!("\"echo: \\\"hello\\\"\"".to_string(), msg.data.to_string()); } else { panic!("bad msg"); From 674cba247e83561c50ca4f84fd71996a17d0f369 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 20:03:07 +0100 Subject: [PATCH 37/45] Swap back ProtocolWrapper::SendResult <> ProtocolWrapper::HandleSendResult --- core/src/network/reducers/send_direct_message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 8e37b00dc0..6c0625fda4 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -22,7 +22,7 @@ fn inner( }; let protocol_object = if direct_message_data.is_response { - ProtocolWrapper::SendResult(data) + ProtocolWrapper::HandleSendResult(data) } else { ProtocolWrapper::SendMessage(data) }; From cebf97d266a9d4826cc2c5d73d8696a4c106abfc Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 20:04:32 +0100 Subject: [PATCH 38/45] rustfmt --- core/src/network/reducers/send_direct_message.rs | 3 ++- core/src/network/state.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 6c0625fda4..9c4da463ec 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -18,7 +18,8 @@ fn inner( dna_hash: network_state.dna_hash.clone().unwrap(), to_agent_id: direct_message_data.address.to_string(), from_agent_id: network_state.agent_id.clone().unwrap(), - data: serde_json::from_str(&serde_json::to_string(&direct_message_data.message).unwrap()).unwrap(), + data: serde_json::from_str(&serde_json::to_string(&direct_message_data.message).unwrap()) + .unwrap(), }; let protocol_object = if direct_message_data.is_response { diff --git a/core/src/network/state.rs b/core/src/network/state.rs index 11a7bbeedd..5a0997ca4c 100644 --- a/core/src/network/state.rs +++ b/core/src/network/state.rs @@ -51,7 +51,7 @@ pub struct NetworkState { /// This stores every open (= waiting for response) node-to-node messages. /// Entries get removed when we receive an answer through Action::ResolveDirectConnection. pub direct_message_connections: HashMap, - + id: snowflake::ProcessUniqueId, } From 142076dab2639df9f84ab4b4e27d05c60a1918f0 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 7 Dec 2018 22:56:51 +0100 Subject: [PATCH 39/45] Error instead of panic --- core/src/network/reducers/get_validation_package.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index e67a891898..e481a8a07d 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -12,7 +12,7 @@ fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), H let source_address = header .sources() .first() - .expect("A header must have at least one source"); + .ok_or(HolochainError::ErrorGeneric("No source found in ChainHeader".to_string()))?; let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); send_message(network_state, source_address, direct_message) From 0165dac15d58fe558f25379a169b65f51d8eb088 Mon Sep 17 00:00:00 2001 From: Eric Harris-Braun Date: Fri, 7 Dec 2018 17:34:34 -0500 Subject: [PATCH 40/45] lint --- core/src/network/reducers/get_validation_package.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/network/reducers/get_validation_package.rs b/core/src/network/reducers/get_validation_package.rs index e481a8a07d..9c879ed150 100644 --- a/core/src/network/reducers/get_validation_package.rs +++ b/core/src/network/reducers/get_validation_package.rs @@ -12,7 +12,9 @@ fn inner(network_state: &mut NetworkState, header: &ChainHeader) -> Result<(), H let source_address = header .sources() .first() - .ok_or(HolochainError::ErrorGeneric("No source found in ChainHeader".to_string()))?; + .ok_or(HolochainError::ErrorGeneric( + "No source found in ChainHeader".to_string(), + ))?; let direct_message = DirectMessage::RequestValidationPackage(header.entry_address().clone()); send_message(network_state, source_address, direct_message) From 39d5132ed871854a7d659c6f2db92646d65ca44d Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Sat, 8 Dec 2018 12:31:52 +0100 Subject: [PATCH 41/45] DirectMessage rustdoc --- core/src/network/direct_message.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/network/direct_message.rs b/core/src/network/direct_message.rs index 36893b1897..265c994bfd 100644 --- a/core/src/network/direct_message.rs +++ b/core/src/network/direct_message.rs @@ -1,7 +1,7 @@ use holochain_core_types::{cas::content::Address, validation::ValidationPackage}; -/// These are the different kind of node-to-node messages -/// that can be send between Holochain nodes. +/// These are the different kinds of (low-level, i.e. non-app) +/// node-to-node messages 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 e70f13feb4c4deebdee113bea58619a386982544 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Sat, 8 Dec 2018 12:44:13 +0100 Subject: [PATCH 42/45] Logging (always panic when logger does not work) --- container_api/src/holochain.rs | 2 +- core/src/context.rs | 12 +++++++---- core/src/network/handler/send.rs | 20 +++++++------------ .../network/reducers/send_direct_message.rs | 4 ++-- core/src/nucleus/ribosome/api/debug.rs | 3 +-- core/src/nucleus/ribosome/run_dna.rs | 11 ++++------ 6 files changed, 23 insertions(+), 29 deletions(-) diff --git a/container_api/src/holochain.rs b/container_api/src/holochain.rs index dc9ec7487c..f91df5ef12 100644 --- a/container_api/src/holochain.rs +++ b/container_api/src/holochain.rs @@ -94,7 +94,7 @@ impl Holochain { ); match result { Ok(_) => { - context.log(&format!("{} instantiated", name))?; + context.log(format!("{} instantiated", name)); let hc = Holochain { instance, context, diff --git a/core/src/context.rs b/core/src/context.rs index 5751a72187..b67007beac 100644 --- a/core/src/context.rs +++ b/core/src/context.rs @@ -85,11 +85,15 @@ impl Context { network_config, }) } + // helper function to make it easier to call the logger - pub fn log(&self, msg: &str) -> Result<(), HolochainError> { - let mut logger = self.logger.lock().or(Err(HolochainError::LoggingError))?; - logger.log(msg.to_string()); - Ok(()) + pub fn log>(&self, msg: T) { + let mut logger = self + .logger + .lock() + .or(Err(HolochainError::LoggingError)) + .expect("Logger should work");; + logger.log(msg.into()); } pub fn set_state(&mut self, state: Arc>) { diff --git a/core/src/network/handler/send.rs b/core/src/network/handler/send.rs index 0bd0ba1d14..24b8529304 100644 --- a/core/src/network/handler/send.rs +++ b/core/src/network/handler/send.rs @@ -11,10 +11,6 @@ use std::{sync::Arc, thread}; use holochain_net_connection::protocol_wrapper::MessageData; -fn log>(context: &Arc, msg: T) { - context.logger.lock().unwrap().log(msg.into()); -} - /// We got a ProtocolWrapper::SendMessage, this means somebody initiates message roundtrip /// -> we are being called pub fn handle_send(message_data: MessageData, context: Arc) { @@ -22,7 +18,7 @@ pub fn handle_send(message_data: MessageData, context: Arc) { serde_json::from_str(&serde_json::to_string(&message_data.data).unwrap()).unwrap(); match message { - DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), + DirectMessage::Custom(_) => context.log("DirectMessage::Custom not implemented"), DirectMessage::RequestValidationPackage(address) => { // Async functions only get executed when they are polled. // I don't want to wait for this workflow to finish here as it would block the @@ -37,11 +33,10 @@ pub fn handle_send(message_data: MessageData, context: Arc) { )); }); } - DirectMessage::ValidationPackage(_) => log( - &context, + DirectMessage::ValidationPackage(_) => context.log( "Got DirectMessage::ValidationPackage as initial message. This should not happen.", ), - } + }; } /// We got a ProtocolWrapper::SendResult, this means somebody has responded to our message @@ -60,14 +55,13 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { .cloned(); match response { - DirectMessage::Custom(_) => log(&context, "DirectMessage::Custom not implemented"), - DirectMessage::RequestValidationPackage(_) => log( - &context, + DirectMessage::Custom(_) => context.log("DirectMessage::Custom not implemented"), + DirectMessage::RequestValidationPackage(_) => context.log( "Got DirectMessage::RequestValidationPackage as a response. This should not happen.", ), DirectMessage::ValidationPackage(maybe_validation_package) => { if initial_message.is_none() { - log(&context, "Received a validation package but could not find message ID in history. Not able to process."); + context.log("Received a validation package but could not find message ID in history. Not able to process."); return; } @@ -84,5 +78,5 @@ pub fn handle_send_result(message_data: MessageData, context: Arc) { ActionWrapper::new(Action::ResolveDirectConnection(message_data.msg_id)); dispatch_action(&context.action_channel, action_wrapper.clone()); } - } + }; } diff --git a/core/src/network/reducers/send_direct_message.rs b/core/src/network/reducers/send_direct_message.rs index 9c4da463ec..5ee4e1cb6e 100644 --- a/core/src/network/reducers/send_direct_message.rs +++ b/core/src/network/reducers/send_direct_message.rs @@ -32,13 +32,13 @@ fn inner( } pub fn reduce_send_direct_message( - _context: Arc, + context: Arc, network_state: &mut NetworkState, action_wrapper: &ActionWrapper, ) { let action = action_wrapper.action(); let dm_data = unwrap_to!(action => crate::action::Action::SendDirectMessage); if let Err(error) = inner(network_state, dm_data) { - println!("Error sending direct message: {:?}", error); + context.log(format!("Error sending direct message: {:?}", error)); } } diff --git a/core/src/nucleus/ribosome/api/debug.rs b/core/src/nucleus/ribosome/api/debug.rs index f684434388..79804667b5 100644 --- a/core/src/nucleus/ribosome/api/debug.rs +++ b/core/src/nucleus/ribosome/api/debug.rs @@ -11,8 +11,7 @@ pub fn invoke_debug(runtime: &mut Runtime, args: &RuntimeArgs) -> ZomeApiResult // TODO #502 - log in logger as DEBUG log-level runtime .context - .log(&format!("zome_log:DEBUG: '{}'", payload)) - .expect("Logger should work"); + .log(format!("zome_log:DEBUG: '{}'", payload)); // Done ribosome_success!() } diff --git a/core/src/nucleus/ribosome/run_dna.rs b/core/src/nucleus/ribosome/run_dna.rs index c0a1e669a4..9f5af48e3f 100644 --- a/core/src/nucleus/ribosome/run_dna.rs +++ b/core/src/nucleus/ribosome/run_dna.rs @@ -168,12 +168,9 @@ pub fn run_dna( } }; // Log & done - runtime - .context - .log(&format!( - "Zome Function '{}' returned: {}", - zome_call.fn_name, return_log_msg, - )) - .expect("Logger should work"); + runtime.context.log(format!( + "Zome Function '{}' returned: {}", + zome_call.fn_name, return_log_msg, + )); return return_result; } From 7673895e33606bf4889b8de5280349625c1f6431 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Sat, 8 Dec 2018 12:50:26 +0100 Subject: [PATCH 43/45] comments --- core/src/action.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index ce8168a542..6c88ca9109 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -132,9 +132,8 @@ pub enum Action { /// Triggered from the network handler. HandleGetResult(DhtData), - /// Sends a direct message object to the given address. - /// 3rd parameter is the message id - /// 4th parameter is true for a response to a previous message, false for a new interaction + /// Makes the network module send a direct (node-to-node) message + /// to the address given in [DirectMessageData](struct.DirectMessageData.html) SendDirectMessage(DirectMessageData), /// Makes the network module forget about the direct message @@ -194,11 +193,22 @@ pub type NetworkReduceFn = ReduceFn; pub type NucleusReduceFn = ReduceFn; pub type ReduceFn = fn(Arc, &mut S, &ActionWrapper); +/// Everything the network module needs to know in order to send a +/// direct message. #[derive(Clone, PartialEq, Debug)] pub struct DirectMessageData { + /// The address of the node to send a message to pub address: Address, + + /// The message itself pub message: DirectMessage, + + /// A unique message ID that is used to identify the response and attribute + /// it to the right context pub msg_id: String, + + /// Should be true if we are responding to a previous message with this message. + /// msg_id should then be the same as the in the message that we received. pub is_response: bool, } From 4c5131950459e98a2ba964333ff71c386b533165 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Sat, 8 Dec 2018 13:06:53 +0100 Subject: [PATCH 44/45] NetworkSettings struct --- core/src/action.rs | 22 +++++++++++++++---- .../src/network/actions/initialize_network.rs | 9 ++++---- core/src/network/reducers/get_entry.rs | 22 +++++++++---------- core/src/network/reducers/init.rs | 12 +++++----- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/core/src/action.rs b/core/src/action.rs index 6c88ca9109..dcccd0dbc8 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -99,10 +99,8 @@ pub enum Action { // ---------------- // 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)), + /// Create a network proxy instance from the given [NetworkSettings](struct.NetworkSettings.html) + InitNetwork(NetworkSettings), /// Makes the network PUT the given entry to the DHT. /// Distinguishes between different entry types and does @@ -212,6 +210,22 @@ pub struct DirectMessageData { pub is_response: bool, } +/// Everything the network needs to initialize +#[derive(Clone, PartialEq, Debug)] +pub struct NetworkSettings { + /// JSON config that gets passed to [P2pNetwork](struct.P2pNetwork.html) + /// determines how to connect to the network module. + pub config: JsonString, + + /// DNA hash is needed so the network module knows which network to + /// connect us to. + pub dna_hash: String, + + /// The network module needs to know who we are. + /// This is this agent's address. + pub agent_id: String, +} + #[cfg(test)] pub mod tests { diff --git a/core/src/network/actions/initialize_network.rs b/core/src/network/actions/initialize_network.rs index 9846f47c75..b8e26840d9 100644 --- a/core/src/network/actions/initialize_network.rs +++ b/core/src/network/actions/initialize_network.rs @@ -1,7 +1,7 @@ extern crate futures; extern crate serde_json; use crate::{ - action::{Action, ActionWrapper}, + action::{Action, ActionWrapper, NetworkSettings}, context::Context, instance::dispatch_action, }; @@ -34,11 +34,12 @@ async fn get_dna_and_agent(context: &Arc) -> Result<(String, String), H /// Creates a network proxy object and stores DNA and agent hash in the network state. pub async fn initialize_network(context: &Arc) -> Result<(), HolochainError> { let (dna_hash, agent_id) = await!(get_dna_and_agent(context))?; - let action_wrapper = ActionWrapper::new(Action::InitNetwork(( - context.network_config.clone(), + let network_settings = NetworkSettings { + config: context.network_config.clone(), dna_hash, agent_id, - ))); + }; + let action_wrapper = ActionWrapper::new(Action::InitNetwork(network_settings)); dispatch_action(&context.action_channel, action_wrapper.clone()); await!(InitNetworkFuture { diff --git a/core/src/network/reducers/get_entry.rs b/core/src/network/reducers/get_entry.rs index 23bcdab0be..cf56d70776 100644 --- a/core/src/network/reducers/get_entry.rs +++ b/core/src/network/reducers/get_entry.rs @@ -71,7 +71,7 @@ pub fn reduce_get_entry_timeout( mod tests { use crate::{ - action::{Action, ActionWrapper}, + action::{Action, ActionWrapper, NetworkSettings}, context::mock_network_config, instance::tests::test_context, state::test_store, @@ -111,11 +111,11 @@ mod tests { let context = test_context("alice"); let store = test_store(context.clone()); - let action_wrapper = ActionWrapper::new(Action::InitNetwork(( - mock_network_config(), - String::from("abcd"), - String::from("abcd"), - ))); + let action_wrapper = ActionWrapper::new(Action::InitNetwork(NetworkSettings { + config: mock_network_config(), + dna_hash: String::from("abcd"), + agent_id: String::from("abcd"), + })); let store = store.reduce(context.clone(), action_wrapper); let entry = test_entry(); @@ -138,11 +138,11 @@ mod tests { Arc::get_mut(&mut context).unwrap().set_state(store.clone()); - let action_wrapper = ActionWrapper::new(Action::InitNetwork(( - mock_network_config(), - String::from("abcd"), - String::from("abcd"), - ))); + let action_wrapper = ActionWrapper::new(Action::InitNetwork(NetworkSettings { + config: mock_network_config(), + dna_hash: String::from("abcd"), + agent_id: String::from("abcd"), + })); { let mut new_store = store.write().unwrap(); diff --git a/core/src/network/reducers/init.rs b/core/src/network/reducers/init.rs index 4b7b041c41..dcd1d5d270 100644 --- a/core/src/network/reducers/init.rs +++ b/core/src/network/reducers/init.rs @@ -16,21 +16,21 @@ pub fn reduce_init( action_wrapper: &ActionWrapper, ) { let action = action_wrapper.action(); - let (_, dna_hash, agent_id) = unwrap_to!(action => Action::InitNetwork); - let mut network = P2pNetwork::new(create_handler(&context), &context.network_config).unwrap(); + let network_settings = unwrap_to!(action => Action::InitNetwork); + let mut network = P2pNetwork::new(create_handler(&context), &network_settings.config).unwrap(); let _ = network .send( ProtocolWrapper::TrackApp(TrackAppData { - dna_hash: dna_hash.clone(), - agent_id: agent_id.clone(), + dna_hash: network_settings.dna_hash.clone(), + agent_id: network_settings.agent_id.clone(), }) .into(), ) .and_then(|_| { state.network = Some(Arc::new(Mutex::new(network))); - state.dna_hash = Some(dna_hash.clone()); - state.agent_id = Some(agent_id.clone()); + state.dna_hash = Some(network_settings.dna_hash.clone()); + state.agent_id = Some(network_settings.agent_id.clone()); Ok(()) }); } From 3b7f21d46a168797fbd223f43fa1ee63833ca6c2 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Sat, 8 Dec 2018 13:27:00 +0100 Subject: [PATCH 45/45] Fix broken merge --- core/src/network/handler/get.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/network/handler/get.rs b/core/src/network/handler/get.rs index c35752f049..f5c611af2d 100644 --- a/core/src/network/handler/get.rs +++ b/core/src/network/handler/get.rs @@ -2,9 +2,8 @@ use crate::{ action::{Action, ActionWrapper}, context::Context, instance::dispatch_action, - network, + nucleus, }; -use futures::executor::block_on; use holochain_core_types::cas::content::Address; use std::sync::Arc; @@ -13,15 +12,18 @@ use holochain_net_connection::protocol_wrapper::{DhtData, GetDhtData}; /// The network has requested a DHT entry from us. /// Lets try to get it and trigger a response. pub fn handle_get_dht(get_dht_data: GetDhtData, context: Arc) { - let _ = block_on(network::actions::get_entry::get_entry( + let maybe_entry_with_meta = nucleus::actions::get_entry::get_entry_with_meta( &context, - &Address::from(get_dht_data.address.clone()), - )) - .map(|maybe_entry_with_meta| { - let action_wrapper = - ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry_with_meta))); - dispatch_action(&context.action_channel, action_wrapper.clone()); + Address::from(get_dht_data.address.clone()), + ) + .unwrap_or_else(|error| { + context.log(format!("Error trying to find entry {:?}", error)); + None }); + + let action_wrapper = + ActionWrapper::new(Action::RespondGet((get_dht_data, maybe_entry_with_meta))); + dispatch_action(&context.action_channel, action_wrapper.clone()); } /// The network comes back with a result to our previous GET request.