Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node): make spend and cash_note reason field configurable #1650

Merged
merged 4 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/memcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
run: |
mkdir -p $BOOTSTRAP_NODE_DATA_PATH
./target/release/safenode --first \
--root-dir $BOOTSTRAP_NODE_DATA_PATH --log-output-dest $BOOTSTRAP_NODE_DATA_PATH --local &
--root-dir $BOOTSTRAP_NODE_DATA_PATH --log-output-dest $BOOTSTRAP_NODE_DATA_PATH --local --owner=maidsafe_test &
sleep 10
env:
SN_LOG: "all"
Expand All @@ -65,7 +65,7 @@ jobs:
run: |
mkdir -p $RESTART_TEST_NODE_DATA_PATH
./target/release/safenode \
--root-dir $RESTART_TEST_NODE_DATA_PATH --log-output-dest $RESTART_TEST_NODE_DATA_PATH --local &
--root-dir $RESTART_TEST_NODE_DATA_PATH --log-output-dest $RESTART_TEST_NODE_DATA_PATH --local --owner=maidsafe_test &
sleep 10
env:
SN_LOG: "all"
Expand Down Expand Up @@ -165,7 +165,7 @@ jobs:
- name: Start the restart node again
run: |
./target/release/safenode \
--root-dir $RESTART_TEST_NODE_DATA_PATH --log-output-dest $RESTART_TEST_NODE_DATA_PATH --local &
--root-dir $RESTART_TEST_NODE_DATA_PATH --log-output-dest $RESTART_TEST_NODE_DATA_PATH --local --owner=maidsafe_test &
sleep 10
env:
SN_LOG: "all"
Expand Down
9 changes: 6 additions & 3 deletions sn_cli/src/bin/subcommands/wallet/wo_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use color_eyre::{
};
use dialoguer::Confirm;
use sn_client::transfers::{
DerivationIndex, MainPubkey, NanoTokens, OfflineTransfer, SignedSpend, UniquePubkey,
CashNoteOutputDetails, MainPubkey, NanoTokens, OfflineTransfer, SignedSpend, UniquePubkey,
WatchOnlyWallet,
};
use sn_client::Client;
Expand Down Expand Up @@ -232,7 +232,10 @@ fn build_unsigned_transaction(from: &str, amount: &str, to: &str, root_dir: &Pat
}
};

let unsigned_transfer = wallet.build_unsigned_transaction(vec![(amount, to)], None)?;
let unsigned_transfer = wallet.build_unsigned_transaction(
vec![("CASH_NOTE_REASON_FOR_TRANSFER".to_string(), amount, to)],
None,
)?;

println!(
"The unsigned transaction has been successfully created:\n\n{}\n",
Expand All @@ -251,7 +254,7 @@ async fn broadcast_signed_spends(
) -> Result<()> {
let (signed_spends, output_details, change_id): (
BTreeSet<SignedSpend>,
BTreeMap<UniquePubkey, (MainPubkey, DerivationIndex)>,
BTreeMap<UniquePubkey, CashNoteOutputDetails>,
UniquePubkey,
) = rmp_serde::from_slice(&hex::decode(signed_tx)?)?;

Expand Down
16 changes: 14 additions & 2 deletions sn_client/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,23 @@
let root_dir = std::env::temp_dir();
trace!("Starting Kad swarm in client mode..{root_dir:?}.");

// TODO: shall client bearing owner's discord user name, to be reflected in the cash_notes?

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment

#[cfg(not(feature = "open-metrics"))]
let network_builder = NetworkBuilder::new(Keypair::generate_ed25519(), local, root_dir);
let network_builder = NetworkBuilder::new(
Keypair::generate_ed25519(),
local,
root_dir,
"maidsafe_client".to_string(),
);

#[cfg(feature = "open-metrics")]
let mut network_builder = NetworkBuilder::new(Keypair::generate_ed25519(), local, root_dir);
let mut network_builder = NetworkBuilder::new(
Keypair::generate_ed25519(),
local,
root_dir,
"maidsafe_client".to_string(),
);
#[cfg(feature = "open-metrics")]
network_builder.metrics_registry(Registry::default());

Expand Down
6 changes: 5 additions & 1 deletion sn_client/src/audit/spend_dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,11 @@ impl SpendDag {
for s in spends {
for derivation_idx in s.spend.network_royalties.iter() {
let spend_addr = SpendAddress::from_unique_pubkey(&s.spend.unique_pubkey);
royalties.push(CashNoteRedemption::new(*derivation_idx, spend_addr));
royalties.push(CashNoteRedemption::new(
*derivation_idx,
spend_addr,
"CASH_NOTE_REASON_FOR_NETWORK_ROYALTIES".to_string(),
));
}
}
Ok(royalties)
Expand Down
1 change: 1 addition & 0 deletions sn_client/src/audit/tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl MockNetwork {
.map_err(|e| eyre!("could not get cashnotes for transfer: {e}"))?;
let recipient = vec![(
NanoTokens::from(amount),
Default::default(),
to_wallet.sk.main_pubkey(),
DerivationIndex::random(&mut rng),
)];
Expand Down
7 changes: 6 additions & 1 deletion sn_client/src/uploader/tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,12 @@ pub fn start_uploading_with_steps(
// Build a very simple client struct for testing. This does not connect to any network.
// The UploaderInterface eliminates the need for direct networking in tests.
pub fn build_unconnected_client(root_dir: PathBuf) -> Result<Client> {
let network_builder = NetworkBuilder::new(Keypair::generate_ed25519(), true, root_dir);
let network_builder = NetworkBuilder::new(
Keypair::generate_ed25519(),
true,
root_dir,
"maidsafe_client".to_string(),
);
let (network, ..) = network_builder.build_client()?;
let client = Client {
network: network.clone(),
Expand Down
13 changes: 8 additions & 5 deletions sn_client/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use sn_networking::target_arch::Instant;
use sn_networking::{GetRecordError, PayeeQuote};
use sn_protocol::NetworkAddress;
use sn_transfers::{
CashNote, DerivationIndex, HotWallet, MainPubkey, NanoTokens, Payment, PaymentQuote,
CashNote, CashNoteOutputDetails, HotWallet, MainPubkey, NanoTokens, Payment, PaymentQuote,
SignedSpend, SpendAddress, Transaction, Transfer, UniquePubkey, WalletError, WalletResult,
};
use std::{
Expand Down Expand Up @@ -306,7 +306,10 @@ impl WalletClient {
to: MainPubkey,
verify_store: bool,
) -> WalletResult<CashNote> {
let created_cash_notes = self.wallet.local_send(vec![(amount, to)], None)?;
let created_cash_notes = self.wallet.local_send(
vec![("CASH_NOTE_REASON_FOR_TRANSFER".to_string(), amount, to)],
None,
)?;

// send to network
if let Err(error) = self
Expand Down Expand Up @@ -346,7 +349,7 @@ impl WalletClient {
signed_spends: BTreeSet<SignedSpend>,
tx: Transaction,
change_id: UniquePubkey,
output_details: BTreeMap<UniquePubkey, (MainPubkey, DerivationIndex)>,
output_details: BTreeMap<UniquePubkey, CashNoteOutputDetails>,
verify_store: bool,
) -> WalletResult<CashNote> {
let created_cash_notes =
Expand Down Expand Up @@ -1086,7 +1089,7 @@ pub async fn send(
/// * signed_spends - [BTreeSet]<[SignedSpend]>,
/// * transaction - [Transaction],
/// * change_id - [UniquePubkey],
/// * output_details - [BTreeMap]<[UniquePubkey], ([MainPubkey], [DerivationIndex])>,
/// * output_details - [BTreeMap]<[UniquePubkey], CashNoteOutputDetails>,
/// * verify_store - Boolean. Set to true for mandatory verification via a GET request through a Spend on the network.
///
/// # Return value
Expand Down Expand Up @@ -1128,7 +1131,7 @@ pub async fn broadcast_signed_spends(
signed_spends: BTreeSet<SignedSpend>,
tx: Transaction,
change_id: UniquePubkey,
output_details: BTreeMap<UniquePubkey, (MainPubkey, DerivationIndex)>,
output_details: BTreeMap<UniquePubkey, CashNoteOutputDetails>,
verify_store: bool,
) -> WalletResult<CashNote> {
let mut wallet_client = WalletClient::new(client.clone(), from);
Expand Down
11 changes: 10 additions & 1 deletion sn_networking/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,11 @@ pub struct NetworkBuilder {
metrics_registry: Option<Registry>,
#[cfg(feature = "open-metrics")]
metrics_server_port: u16,
owner: String,
}

impl NetworkBuilder {
pub fn new(keypair: Keypair, local: bool, root_dir: PathBuf) -> Self {
pub fn new(keypair: Keypair, local: bool, root_dir: PathBuf, owner: String) -> Self {
Self {
is_behind_home_network: false,
keypair,
Expand All @@ -223,6 +224,7 @@ impl NetworkBuilder {
metrics_registry: None,
#[cfg(feature = "open-metrics")]
metrics_server_port: 0,
owner,
}
}

Expand Down Expand Up @@ -315,13 +317,15 @@ impl NetworkBuilder {
};

let listen_addr = self.listen_addr;
let owner = self.owner.clone();

let (network, events_receiver, mut swarm_driver) = self.build(
kad_cfg,
Some(store_cfg),
false,
ProtocolSupport::Full,
IDENTIFY_NODE_VERSION_STR.to_string(),
owner,
)?;

// Listen on the provided address
Expand Down Expand Up @@ -367,12 +371,15 @@ impl NetworkBuilder {
.ok_or_else(|| NetworkError::InvalidCloseGroupSize)?,
);

let owner = self.owner.clone();

let (network, net_event_recv, driver) = self.build(
kad_cfg,
None,
true,
ProtocolSupport::Outbound,
IDENTIFY_CLIENT_VERSION_STR.to_string(),
owner,
)?;

Ok((network, net_event_recv, driver))
Expand All @@ -386,6 +393,7 @@ impl NetworkBuilder {
is_client: bool,
req_res_protocol: ProtocolSupport,
identify_version: String,
owner: String,
) -> Result<(Network, mpsc::Receiver<NetworkEvent>, SwarmDriver)> {
let peer_id = PeerId::from(self.keypair.public());
// vdash metric (if modified please notify at https://github.com/happybeing/vdash/issues):
Expand Down Expand Up @@ -579,6 +587,7 @@ impl NetworkBuilder {
peer_id: Arc::new(peer_id),
root_dir_path: Arc::new(self.root_dir),
keypair: Arc::new(self.keypair),
owner,
},
network_event_receiver,
swarm_driver,
Expand Down
17 changes: 14 additions & 3 deletions sn_networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,16 @@ pub struct Network {
pub peer_id: Arc<PeerId>,
pub root_dir_path: Arc<PathBuf>,
keypair: Arc<Keypair>,
/// node owner's discord username, in readable format
owner: String,
}

impl Network {
/// Returns of the discord user_name of the node's owner
pub fn owner(&self) -> String {
self.owner.clone()
}

/// Signs the given data with the node's keypair.
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>> {
self.keypair.sign(msg).map_err(NetworkError::from)
Expand Down Expand Up @@ -1046,9 +1053,13 @@ mod tests {

#[test]
fn test_network_sign_verify() -> eyre::Result<()> {
let (network, _, _) =
NetworkBuilder::new(Keypair::generate_ed25519(), false, std::env::temp_dir())
.build_client()?;
let (network, _, _) = NetworkBuilder::new(
Keypair::generate_ed25519(),
false,
std::env::temp_dir(),
"maidsafe_test".to_string(),
)
.build_client()?;
let msg = b"test message";
let sig = network.sign(msg)?;
assert!(network.verify(msg, &sig));
Expand Down
18 changes: 10 additions & 8 deletions sn_networking/src/transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,17 @@ impl Network {
parent_spends.iter().map(|s| s.spent_tx()).collect();

// get our outputs from Tx
let our_output_unique_pubkeys: Vec<(UniquePubkey, DerivationIndex)> = cashnote_redemptions
.iter()
.map(|u| {
let unique_pubkey = main_pubkey.new_unique_pubkey(&u.derivation_index);
(unique_pubkey, u.derivation_index)
})
.collect();
let our_output_unique_pubkeys: Vec<(String, UniquePubkey, DerivationIndex)> =
cashnote_redemptions
.iter()
.map(|u| {
let unique_pubkey = main_pubkey.new_unique_pubkey(&u.derivation_index);
(u.reason.clone(), unique_pubkey, u.derivation_index)
})
.collect();
let mut our_output_cash_notes = Vec::new();

for (id, derivation_index) in our_output_unique_pubkeys.into_iter() {
for (reason, id, derivation_index) in our_output_unique_pubkeys.into_iter() {
let src_tx = parent_txs
.iter()
.find(|tx| tx.outputs.iter().any(|o| o.unique_pubkey() == &id))
Expand All @@ -169,6 +170,7 @@ impl Network {
unique_pubkey: id,
parent_tx: src_tx,
parent_spends: signed_spends,
reason: reason.clone(),
main_pubkey,
derivation_index,
};
Expand Down
5 changes: 5 additions & 0 deletions sn_node/src/bin/safenode/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ struct Opt {
#[clap(long)]
local: bool,

/// Specify the owner(readable discord user name).
#[clap(long)]
owner: String,

#[cfg(feature = "open-metrics")]
/// Specify the port for the OpenMetrics server.
///
Expand Down Expand Up @@ -195,6 +199,7 @@ fn main() -> Result<()> {
bootstrap_peers,
opt.local,
root_dir,
opt.owner.clone(),
);
node_builder.is_behind_home_network = opt.home_network;
#[cfg(feature = "open-metrics")]
Expand Down
6 changes: 5 additions & 1 deletion sn_node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub struct NodeBuilder {
metrics_server_port: u16,
/// Enable hole punching for nodes connecting from home networks.
pub is_behind_home_network: bool,
owner: String,
}

impl NodeBuilder {
Expand All @@ -77,6 +78,7 @@ impl NodeBuilder {
initial_peers: Vec<Multiaddr>,
local: bool,
root_dir: PathBuf,
owner: String,
) -> Self {
Self {
keypair,
Expand All @@ -87,6 +89,7 @@ impl NodeBuilder {
#[cfg(feature = "open-metrics")]
metrics_server_port: 0,
is_behind_home_network: false,
owner,
}
}

Expand Down Expand Up @@ -130,7 +133,8 @@ impl NodeBuilder {
(metrics_registry, node_metrics)
};

let mut network_builder = NetworkBuilder::new(self.keypair, self.local, self.root_dir);
let mut network_builder =
NetworkBuilder::new(self.keypair, self.local, self.root_dir, self.owner.clone());

network_builder.listen_addr(self.addr);
#[cfg(feature = "open-metrics")]
Expand Down
9 changes: 9 additions & 0 deletions sn_node/src/put_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ impl Node {
let record_key = record.key.clone();
let value_to_hash = record.value.clone();
let spends = try_deserialize_record::<Vec<SignedSpend>>(&record)?;

let pretty_key = PrettyPrintRecordKey::from(&record_key);
for spend in spends.iter() {
trace!(
"Spend record {pretty_key:?} has output purposes of {:?}",
spend.spend.output_purposes()
);
}

let result = self.validate_and_store_spends(spends, &record_key).await;
if result.is_ok() {
Marker::ValidSpendPutFromClient(&PrettyPrintRecordKey::from(&record_key)).log();
Expand Down
Loading
Loading