use crate::{
node_ops::{NodeDuties, NodeDuty, OutgoingMsg},
section_funds::{self, SectionFunds},
transfers::{
replica_signing::ReplicaSigningImpl,
replicas::{ReplicaInfo, Replicas},
},
Error, Node, Result,
};
use dashmap::DashMap;
use log::{debug, info};
use section_funds::{
elder_signing::ElderSigning,
reward_process::{OurSection, RewardProcess},
reward_stage::RewardStage,
reward_wallets::RewardWallets,
Credits,
};
use sn_data_types::{
ActorHistory, CreditAgreementProof, CreditId, NodeAge, PublicKey, SectionElders, Token,
WalletHistory,
};
use sn_messaging::{
client::{
Message, NodeCmd, NodeEvent, NodeQuery, NodeQueryResponse, NodeSystemCmd, NodeSystemQuery,
NodeSystemQueryResponse, NodeTransferCmd,
},
Aggregation, DstLocation, MessageId, SrcLocation,
};
use sn_routing::{Prefix, XorName};
use sn_transfers::TransferActor;
use std::collections::BTreeMap;
impl Node {
pub(crate) fn propagate_credits(
credit_proofs: BTreeMap<CreditId, CreditAgreementProof>,
) -> Result<NodeDuties> {
use NodeCmd::*;
use NodeTransferCmd::*;
let mut ops = vec![];
for (_, credit_proof) in credit_proofs {
let location = XorName::from(credit_proof.recipient());
let msg_id = MessageId::from_content(&credit_proof.debiting_replicas_sig)?;
ops.push(NodeDuty::Send(OutgoingMsg {
msg: Message::NodeCmd {
cmd: Transfers(PropagateTransfer(credit_proof)),
id: msg_id,
target_section_pk: None,
},
section_source: true,
dst: DstLocation::Section(location),
aggregation: Aggregation::AtDestination,
}))
}
Ok(ops)
}
#[allow(clippy::eval_order_dependence)]
pub(crate) async fn get_section_elders(
&self,
msg_id: MessageId,
origin: SrcLocation,
) -> Result<NodeDuty> {
let elders = SectionElders {
prefix: self.network_api.our_prefix().await,
names: self.network_api.our_elder_names().await,
key_set: self.network_api.our_public_key_set().await?,
};
Ok(NodeDuty::Send(OutgoingMsg {
msg: Message::NodeQueryResponse {
response: NodeQueryResponse::System(NodeSystemQueryResponse::GetSectionElders(
elders,
)),
correlation_id: msg_id,
id: MessageId::in_response_to(&msg_id),
target_section_pk: None,
},
section_source: false,
dst: origin.to_dst(),
aggregation: Aggregation::AtDestination,
}))
}
pub(crate) async fn notify_section_of_our_storage(&mut self) -> Result<NodeDuty> {
let node_id = PublicKey::from(self.network_api.public_key().await);
Ok(NodeDuty::Send(OutgoingMsg {
msg: Message::NodeCmd {
cmd: NodeCmd::System(NodeSystemCmd::StorageFull {
section: node_id.into(),
node_id,
}),
id: MessageId::new(),
target_section_pk: None,
},
section_source: false,
dst: DstLocation::Section(node_id.into()),
aggregation: Aggregation::None,
}))
}
pub(crate) async fn register_wallet(&self) -> OutgoingMsg {
let address = self.network_api.our_prefix().await.name();
OutgoingMsg {
msg: Message::NodeCmd {
cmd: NodeCmd::System(NodeSystemCmd::RegisterWallet(self.node_info.reward_key)),
id: MessageId::new(),
target_section_pk: None,
},
section_source: false,
dst: DstLocation::Section(address),
aggregation: Aggregation::None,
}
}
pub fn push_state(&self, prefix: Prefix, msg_id: MessageId) -> NodeDuty {
let dst = DstLocation::Section(prefix.name());
let user_wallets = if let Ok(elder) = &self.role.as_elder() {
elder.transfers.user_wallets()
} else {
BTreeMap::new()
};
let node_rewards = if let Ok(elder) = &self.role.as_elder() {
elder.section_funds.node_wallets()
} else {
BTreeMap::new()
};
let user_wallets = user_wallets
.into_iter()
.filter(|(key, _)| dst.contains(&XorName::from(*key), &prefix))
.collect();
let node_rewards = node_rewards
.into_iter()
.filter(|(name, _)| dst.contains(name, &prefix))
.collect();
NodeDuty::Send(OutgoingMsg {
msg: Message::NodeCmd {
cmd: NodeCmd::System(NodeSystemCmd::ReceiveExistingData {
node_rewards,
user_wallets,
}),
id: msg_id,
target_section_pk: None,
},
section_source: false,
dst,
aggregation: Aggregation::None,
})
}
}