Skip to content

Commit

Permalink
feat(royalties): make royalties payment to be 15% of the total storag…
Browse files Browse the repository at this point in the history
…e cost
  • Loading branch information
bochaco committed Nov 14, 2023
1 parent a616a7a commit ffa9cc5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 39 deletions.
20 changes: 9 additions & 11 deletions sn_node/src/put_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ use sn_protocol::{
};
use sn_registers::SignedRegister;
use sn_transfers::{
is_genesis_parent_tx, CashNoteRedemption, LocalWallet, Transfer, GENESIS_CASHNOTE,
NETWORK_ROYALTIES_PK,
};
use sn_transfers::{
CashNote, NanoTokens, SignedSpend, UniquePubkey, NETWORK_ROYALTIES_AMOUNT_PER_ADDR,
calculate_royalties_fee, is_genesis_parent_tx, CashNote, CashNoteRedemption, LocalWallet,
NanoTokens, SignedSpend, Transfer, UniquePubkey, GENESIS_CASHNOTE, NETWORK_ROYALTIES_PK,
};
use std::collections::{BTreeSet, HashSet};
use xor_name::XorName;
Expand Down Expand Up @@ -550,16 +547,17 @@ impl Node {
}

// check payment is sufficient both for our store cost and for network royalties
let expected_fee = self
.network
.get_local_storecost()
.await
.map_err(|e| ProtocolError::RecordNotStored(pretty_key.clone(), format!("{e:?}")))?
.checked_add(NETWORK_ROYALTIES_AMOUNT_PER_ADDR)
let local_storecost =
self.network.get_local_storecost().await.map_err(|e| {
ProtocolError::RecordNotStored(pretty_key.clone(), format!("{e:?}"))
})?;
let expected_fee = local_storecost
.checked_add(calculate_royalties_fee(local_storecost))
.ok_or(ProtocolError::RecordNotStored(
pretty_key.clone(),
"CashNote value overflow".to_string(),
))?;

// finally, (after we accept any payments to us as they are ours now anyway)
// lets check they actually paid enough
if received_fee < expected_fee {
Expand Down
5 changes: 2 additions & 3 deletions sn_node/tests/nodes_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,15 @@ async fn nodes_rewards_transfer_notifs_filter() -> Result<()> {
println!("Random chunks stored, paid {storage_cost}/{royalties_fees}");

let count_1 = handle_1.await??;
let expected = royalties_fees.as_nano() as usize;
println!("Number of notifications received by node #1: {count_1}");
let count_2 = handle_2.await??;
println!("Number of notifications received by node #2: {count_2}");
let count_3 = handle_3.await??;
println!("Number of notifications received by node #3: {count_3}");

assert!(
count_1 >= expected,
"expected: {expected:?}, received {count_1:?}... Not enough notifications received"
count_1 >= num_of_chunks,
"expected: {num_of_chunks:?}, received {count_1:?}... Not enough notifications received"
);
assert_eq!(count_2, 0, "Notifications were not expected");
assert_eq!(count_3, 0, "Notifications were not expected");
Expand Down
8 changes: 6 additions & 2 deletions sn_transfers/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ use thiserror::Error;
/// thus creating a total of 1,288,490,189,000,000,000 available units.
pub(super) const GENESIS_CASHNOTE_AMOUNT: u64 = (0.3 * TOTAL_SUPPLY as f64) as u64;

/// Expected amount to be paid as network royalties for each record to be stored.
pub const NETWORK_ROYALTIES_AMOUNT_PER_ADDR: NanoTokens = NanoTokens::from(1);
/// Based on the given store cost, it calculates what's the expected amount to be paid as network royalties.
/// Network royalties fee is expected to be 15% of the total store cost.
pub fn calculate_royalties_fee(store_cost: NanoTokens) -> NanoTokens {
let fees_amount = (store_cost.as_nano() as f64 * 0.15) / 0.85;
NanoTokens::from(fees_amount as u64)
}

/// A specialised `Result` type for genesis crate.
pub(super) type GenesisResult<T> = Result<T, Error>;
Expand Down
9 changes: 3 additions & 6 deletions sn_transfers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ pub use transfers::{CashNoteRedemption, OfflineTransfer, Transfer};

/// Utilities exposed
pub use genesis::{
create_faucet_wallet, create_first_cash_note_from_key, is_genesis_parent_tx,
load_genesis_wallet,
};
pub use genesis::{
Error as GenesisError, GENESIS_CASHNOTE, GENESIS_CASHNOTE_SK,
NETWORK_ROYALTIES_AMOUNT_PER_ADDR, NETWORK_ROYALTIES_PK,
calculate_royalties_fee, create_faucet_wallet, create_first_cash_note_from_key,
is_genesis_parent_tx, load_genesis_wallet, Error as GenesisError, GENESIS_CASHNOTE,
GENESIS_CASHNOTE_SK, NETWORK_ROYALTIES_PK,
};
pub use transfers::create_offline_transfer;
pub use wallet::{bls_secret_from_hex, parse_main_pubkey};
Expand Down
40 changes: 23 additions & 17 deletions sn_transfers/src/wallet/local_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ use super::{
};

use crate::{
calculate_royalties_fee,
transfers::{create_offline_transfer, ContentPaymentsIdMap, OfflineTransfer, PaymentDetails},
CashNote, CashNoteRedemption, DerivationIndex, DerivedSecretKey, Hash, MainPubkey,
MainSecretKey, NanoTokens, SignedSpend, Transfer, UniquePubkey, WalletError,
NETWORK_ROYALTIES_AMOUNT_PER_ADDR, NETWORK_ROYALTIES_PK,
NETWORK_ROYALTIES_PK,
};
use xor_name::XorName;

Expand Down Expand Up @@ -308,27 +309,16 @@ impl LocalWallet {
let mut all_payees_only = vec![];
let mut rng = &mut rand::thread_rng();

// we currently pay 1 nano per address as network royalties.
let royalties_pk = *crate::NETWORK_ROYALTIES_PK;

let mut storage_cost = NanoTokens::zero();
let mut royalties_fees = NanoTokens::zero();

for (_content_addr, payees) in all_data_payments.iter_mut() {
// add network royalties payment as payee for each address being payed
payees.push((royalties_pk, NETWORK_ROYALTIES_AMOUNT_PER_ADDR));

let mut cost = NanoTokens::zero();
let mut unique_key_vec = Vec::<(NanoTokens, MainPubkey, [u8; 32])>::new();
for (address, amount) in payees.clone().into_iter() {
if address == *NETWORK_ROYALTIES_PK {
royalties_fees = royalties_fees
.checked_add(amount)
.ok_or(WalletError::TotalPriceTooHigh)?;
} else {
storage_cost = storage_cost
.checked_add(amount)
.ok_or(WalletError::TotalPriceTooHigh)?;
}
cost = cost
.checked_add(amount)
.ok_or(WalletError::TotalPriceTooHigh)?;

unique_key_vec.push((
amount,
Expand All @@ -337,6 +327,22 @@ impl LocalWallet {
));
}

storage_cost = storage_cost
.checked_add(cost)
.ok_or(WalletError::TotalPriceTooHigh)?;

// add network royalties payment as payee for each address being payed
let royalties = calculate_royalties_fee(cost);
payees.push((*NETWORK_ROYALTIES_PK, royalties));
royalties_fees = royalties_fees
.checked_add(royalties)
.ok_or(WalletError::TotalPriceTooHigh)?;
unique_key_vec.push((
royalties,
*NETWORK_ROYALTIES_PK,
UniquePubkey::random_derivation_index(&mut rng),
));

all_payees_only.extend(unique_key_vec);
}

Expand Down Expand Up @@ -372,7 +378,7 @@ impl LocalWallet {
let value = cash_note.value();

// diffentiate between network royalties and storage payments
if cash_note.main_pubkey == *crate::NETWORK_ROYALTIES_PK {
if cash_note.main_pubkey == *NETWORK_ROYALTIES_PK {
trace!("Created netowrk royalties transaction regarding {content_addr:?} paying {value:?}(origin {token:?}) to payee {payee:?}.");
cash_notes_for_content.push((
Transfer::royalties_transfers_from_cash_note(cash_note.to_owned())?,
Expand Down

0 comments on commit ffa9cc5

Please sign in to comment.