Skip to content

Commit

Permalink
feat(rewards): adds query to get Elder reward keys
Browse files Browse the repository at this point in the history
  • Loading branch information
oetyng authored and joshuef committed Mar 9, 2023
1 parent 07b4cb7 commit 7789cd5
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 33 deletions.
8 changes: 4 additions & 4 deletions sn_client/src/api/spentbook_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use sn_dbc::{DbcTransaction, PublicKey, SpentProof, SpentProofShare};
use sn_interface::{
dbcs::DbcReason,
messaging::data::{
DataCmd, DataQuery, Error as NetworkDataError, QueryResponse, SpentbookCmd, SpentbookQuery,
DataCmd, DataQuery, Error as NetworkDataError, QueryResponse, SpendQuery, SpentbookCmd,
},
types::SpentbookAddress,
};
Expand Down Expand Up @@ -103,17 +103,17 @@ impl Client {
}

//----------------------
// Read Spentbook
// Spend related reads
//---------------------

/// Return the set of spent proof shares if the provided DBC's public key is spent
#[instrument(skip(self), level = "debug")]
pub async fn spent_proof_shares(&self, public_key: PublicKey) -> Result<Vec<SpentProofShare>> {
let address = SpentbookAddress::new(XorName::from_content(&public_key.to_bytes()));
let query = DataQuery::Spentbook(SpentbookQuery::SpentProofShares(address));
let query = DataQuery::Spentbook(SpendQuery::GetSpentProofShares(address));
let response = self.send_query(query.clone()).await?;
match response {
QueryResponse::SpentProofShares(res) => {
QueryResponse::GetSpentProofShares(res) => {
res.map_err(|err| Error::ErrorMsg { source: err })
}
other => Err(Error::UnexpectedQueryResponse {
Expand Down
8 changes: 4 additions & 4 deletions sn_client/src/sessions/messaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{Error, Result};

use sn_interface::{
messaging::{
data::{DataQuery, QueryResponse},
data::{DataQuery, QueryResponse, SpendQuery},
ClientAuth, Dst, MsgId, MsgKind, WireMsg,
},
network_knowledge::supermajority,
Expand Down Expand Up @@ -359,7 +359,7 @@ impl Session {
};
let kind = MsgKind::Client {
auth,
is_spend: false,
is_spend: matches!(query, DataQuery::Spentbook(SpendQuery::GetFees(_))),
query_index: Some(query_node_index),
};
let wire_msg = WireMsg::new_msg(msg_id, payload, kind, dst);
Expand Down Expand Up @@ -469,10 +469,10 @@ impl Session {
valid_response = Some(*response);
}
}
QueryResponse::SpentProofShares(Ok(ref spentproof_set)) => {
QueryResponse::GetSpentProofShares(Ok(ref spentproof_set)) => {
debug!("okay _read_ spentproofs from {node_address:?}");
// TODO: properly merge all registers
if let Some(QueryResponse::SpentProofShares(Ok(prior_response))) =
if let Some(QueryResponse::GetSpentProofShares(Ok(prior_response))) =
&valid_response
{
if spentproof_set.len() > prior_response.len() {
Expand Down
11 changes: 7 additions & 4 deletions sn_interface/src/messaging/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use self::{
CreateRegister, EditRegister, RegisterCmd, RegisterQuery, SignedRegisterCreate,
SignedRegisterEdit,
},
spentbook::{SpentbookCmd, SpentbookQuery},
spentbook::{SpendQuery, SpentbookCmd},
};

use crate::types::{
Expand Down Expand Up @@ -140,8 +140,11 @@ pub enum QueryResponse {
//
// ===== Spentbook Data =====
//
/// Response to [`SpentbookQuery::SpentProofShares`].
SpentProofShares(Result<Vec<SpentProofShare>>),
/// Response to [`SpendQuery::GetSpentProofShares`].
GetSpentProofShares(Result<Vec<SpentProofShare>>),
//
/// Response to [`SpendQuery::GetFees`].
GetFees(Result<(bls::PublicKey, sn_dbc::Token)>),
}

impl QueryResponse {
Expand All @@ -161,7 +164,7 @@ impl QueryResponse {
| GetRegisterPolicy(Err(Error::NoSuchUser(_)))
| GetRegisterUserPermissions(Err(Error::DataNotFound(_)))
| GetRegisterUserPermissions(Err(Error::NoSuchUser(_)))
| SpentProofShares(Err(Error::DataNotFound(_)))
| GetSpentProofShares(Err(Error::DataNotFound(_)))
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions sn_interface/src/messaging/data/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use super::{register::RegisterQuery, spentbook::SpentbookQuery};
use super::{register::RegisterQuery, spentbook::SpendQuery};
use crate::types::ChunkAddress;
use serde::{Deserialize, Serialize};
use xor_name::XorName;
Expand All @@ -32,7 +32,7 @@ pub enum DataQuery {
/// [`Register`]: crate::types::register::Register
Register(RegisterQuery),
/// Spentbook read operation.
Spentbook(SpentbookQuery),
Spentbook(SpendQuery),
}

impl DataQuery {
Expand Down
18 changes: 11 additions & 7 deletions sn_interface/src/messaging/data/spentbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ use sn_dbc::{DbcTransaction, PublicKey, SpentProof};
use std::collections::BTreeSet;
use xor_name::XorName;

/// Spentbook read operations.
/// Spend related read operations.
#[derive(Hash, Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
pub enum SpentbookQuery {
/// Query the set of spent proofs if the provided public key has already been spent with a Tx
SpentProofShares(SpentbookAddress),
pub enum SpendQuery {
/// Query for the individual reward keys and their respective fee amount for processing a `Spend`.
GetFees(SpentbookAddress),
/// Query for the set of spent proofs if the provided public key has already been spent with a Tx.
GetSpentProofShares(SpentbookAddress),
}

/// A Spentbook cmd.
Expand Down Expand Up @@ -60,19 +62,21 @@ impl SpentbookCmd {
}
}

impl SpentbookQuery {
impl SpendQuery {
/// Creates a Response containing an error, with the Response variant corresponding to the
/// Request variant.
pub fn to_error_response(&self, error: Error) -> QueryResponse {
match self {
Self::SpentProofShares(_) => QueryResponse::SpentProofShares(Err(error)),
Self::GetFees(_) => QueryResponse::GetFees(Err(error)),
Self::GetSpentProofShares(_) => QueryResponse::GetSpentProofShares(Err(error)),
}
}

/// Returns the dst address for the request.
pub fn dst_address(&self) -> SpentbookAddress {
match self {
Self::SpentProofShares(address) => *address,
Self::GetFees(address) => *address,
Self::GetSpentProofShares(address) => *address,
}
}

Expand Down
2 changes: 2 additions & 0 deletions sn_interface/src/messaging/msg_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub enum MsgKind {
// TODO: Should query index be a part of Dst?
Client {
auth: ClientAuth,
/// This is `true` if the msg is to be handled first/directly at Elders,
/// such as a spend or a fee query. (FIX: This pattern is quite confusing.)
is_spend: bool,
query_index: Option<usize>,
},
Expand Down
44 changes: 37 additions & 7 deletions sn_node/src/node/messaging/client_msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use sn_dbc::{
use sn_interface::{
dbcs::DbcReason,
messaging::{
data::{ClientMsg, DataCmd, DataQuery, DataResponse, SpentbookCmd},
data::{ClientMsg, DataCmd, DataQuery, DataResponse, SpendQuery, SpentbookCmd},
system::NodeQueryResponse,
AuthorityProof, ClientAuth, MsgId,
},
network_knowledge::{
Expand Down Expand Up @@ -48,10 +49,15 @@ impl MyNode {
send_stream: SendStream,
context: NodeContext,
) -> Vec<Cmd> {
let response = context
.data_storage
.query(query, User::Key(auth.public_key))
.await;
let response = if let DataQuery::Spentbook(SpendQuery::GetFees(_)) = query {
// We receive this directly from client, as an Elder, since `is_spend` is set to true (that is a very messy/confusing pattern, to be fixed).
NodeQueryResponse::GetFees(Ok((context.reward_key, context.store_cost)))
} else {
context
.data_storage
.query(query, User::Key(auth.public_key))
.await
};

trace!("{msg_id:?} data query response at node is: {response:?}");

Expand Down Expand Up @@ -233,7 +239,7 @@ impl MyNode {
context: &NodeContext,
) -> Result<SpentProofShare> {
// verify that fee is paid (we are included as output)
MyNode::verify_fee(context.reward_key, tx)?;
MyNode::verify_fee(context.store_cost, context.reward_key, tx)?;

// verify the spent proofs
MyNode::verify_spent_proofs(spent_proofs, &context.network_knowledge)?;
Expand Down Expand Up @@ -280,8 +286,32 @@ impl MyNode {
Ok(spent_proof_share)
}

fn verify_fee(_our_key: PublicKey, _tx: &DbcTransaction) -> Result<()> {
fn verify_fee(
_store_cost: sn_dbc::Token,
_our_key: PublicKey,
_tx: &DbcTransaction,
) -> Result<()> {
// TODO: check that we have an output to us, and that it is of sufficient value.

// pseudo code:

// let paid_to_us = match tx.get(our_key) {
// Some(output) => output.amount(),
// None => {
// return Err(Error::InsufficientFeesPaid {
// min_required: store_cost,
// paid: sn_dbc::Token::zero(),
// })
// }
// };

// if store_cost > paid_to_us {
// return Err(Error::InsufficientFeesPaid {
// min_required: store_cost,
// paid: paid_to_us,
// });
// }

Ok(())
}

Expand Down
2 changes: 2 additions & 0 deletions sn_node/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ mod core {
pub(crate) info: MyNodeInfo,
pub(crate) keypair: Arc<Keypair>,
pub(crate) reward_key: PublicKey,
pub(crate) store_cost: sn_dbc::Token,
pub(crate) network_knowledge: NetworkKnowledge,
pub(crate) section_keys_provider: SectionKeysProvider,
#[debug(skip)]
Expand Down Expand Up @@ -188,6 +189,7 @@ mod core {
info: self.info(),
keypair: self.keypair.clone(),
reward_key: self.reward_key,
store_cost: sn_dbc::Token::from_nano(1), // hard coded for now
network_knowledge: self.network_knowledge().clone(),
section_keys_provider: self.section_keys_provider.clone(),
comm: self.comm.clone(),
Expand Down
14 changes: 9 additions & 5 deletions sn_node/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use registers::RegisterStorage;
use sn_dbc::SpentProofShare;
use sn_interface::{
messaging::{
data::{DataQuery, Error as MessagingError, RegisterQuery},
data::{DataQuery, Error as MessagingError, RegisterQuery, SpendQuery},
system::NodeQueryResponse,
},
types::{
Expand Down Expand Up @@ -140,18 +140,18 @@ impl DataStorage {
match query {
DataQuery::GetChunk(addr) => self.chunks.get(addr).await,
DataQuery::Register(read) => self.registers.read(read, requester).await,
DataQuery::Spentbook(read) => {
DataQuery::Spentbook(SpendQuery::GetSpentProofShares(addr)) => {
// TODO: this is temporary till spentbook native data type is implemented,
// we read from the Register where we store the spentbook data
let reg_addr = RegisterAddress::new(read.dst_name(), SPENTBOOK_TYPE_TAG);
let reg_addr = RegisterAddress::new(*addr.name(), SPENTBOOK_TYPE_TAG);

match self
.registers
.read(&RegisterQuery::Get(reg_addr), requester)
.await
{
NodeQueryResponse::GetRegister(Err(MessagingError::DataNotFound(_))) => {
NodeQueryResponse::SpentProofShares(Ok(Vec::new()))
NodeQueryResponse::GetSpentProofShares(Ok(Vec::new()))
}
NodeQueryResponse::GetRegister(result) => {
let proof_shares_result = result.map(|reg| {
Expand All @@ -172,7 +172,7 @@ impl DataStorage {
proof_shares
});

NodeQueryResponse::SpentProofShares(proof_shares_result)
NodeQueryResponse::GetSpentProofShares(proof_shares_result)
}
other => {
// TODO: this is temporary till spentbook native data type is implemented,
Expand All @@ -181,6 +181,10 @@ impl DataStorage {
}
}
}
// this should be unreachable
DataQuery::Spentbook(SpendQuery::GetFees(addr)) => NodeQueryResponse::GetFees(Err(
sn_interface::messaging::data::Error::DataNotFound(DataAddress::Spentbook(*addr)),
)),
}
}

Expand Down

0 comments on commit 7789cd5

Please sign in to comment.