Skip to content

Commit

Permalink
feat: allow register CLI to create a public register writable to anyone
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasmarkiewicz committed Jan 9, 2024
1 parent 3cfcdbc commit bb3d801
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 42 deletions.
64 changes: 58 additions & 6 deletions .github/workflows/merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,18 @@ jobs:
PROPTEST_CASES: 50

e2e:
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
name: E2E tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
safe_path: /home/runner/.local/share/safe
- os: windows-latest
safe_path: C:\\Users\\runneradmin\\AppData\\Roaming\\safe
- os: macos-latest
safe_path: /Users/runner/Library/Application Support/safe
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -160,6 +166,7 @@ jobs:
fi
- name: Create and fund a wallet to pay for files storage
shell: bash
run: |
cargo run --bin faucet --release -- --log-output-dest=data-dir send 1000000 $(cargo run --bin safe --release -- --log-output-dest=data-dir wallet address | tail -n 1) | tail -n 1 > transfer_hex
cargo run --bin safe --release -- --log-output-dest=data-dir wallet receive --file transfer_hex
Expand All @@ -168,35 +175,80 @@ jobs:
timeout-minutes: 5

- name: Start a client to upload files
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir files upload "./resources" -r 0
env:
SN_LOG: "all"
timeout-minutes: 15

- name: Start a client to download files
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir files download
env:
SN_LOG: "all"
timeout-minutes: 2

- name: Start a client to create a register
- name: Start a client to create a register writable by the owner only
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register create -n baobao
env:
SN_LOG: "all"
timeout-minutes: 10

- name: Start a client to get a register
- name: Start a client to get a register writable by the owner only
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register get -n baobao
env:
SN_LOG: "all"
timeout-minutes: 2

- name: Start a client to edit a register
- name: Start a client to edit a register writable by the owner only
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register edit -n baobao wood
env:
SN_LOG: "all"
timeout-minutes: 10

- name: Start a client to create a register writable by anyone
id: register-address
shell: bash
run: echo "$(cargo run --bin safe --release -- --log-output-dest=data-dir register create -n trycatch -p | rg REGISTER_ADDRESS )" >> $GITHUB_OUTPUT
env:
SN_LOG: "all"
timeout-minutes: 10

- name: Start a client to get a register writable by anyone (current client is the owner)
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register get -n trycatch
env:
SN_LOG: "all"
timeout-minutes: 2

- name: Start a client to edit a register writable by anyone (current client is the owner)
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register edit -n trycatch wood
env:
SN_LOG: "all"
timeout-minutes: 10

- name: Delete client subdir to generate new client
shell: bash
run: rm -rf ${{ matrix.safe_path }}/client

- name: Start a client to get a register writable by anyone (new client is not the owner)
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register get ${{ steps.register-address.outputs.REGISTER_ADDRESS }}
env:
SN_LOG: "all"
timeout-minutes: 2

- name: Start a client to edit a register writable by anyone (new client is not the owner)
shell: bash
run: cargo run --bin safe --release -- --log-output-dest=data-dir register edit ${{ steps.register-address.outputs.REGISTER_ADDRESS }} water
env:
SN_LOG: "all"
timeout-minutes: 10

- name: Stop the local network and upload logs
if: always()
uses: maidsafe/sn-local-testnet-action@main
Expand Down Expand Up @@ -646,4 +698,4 @@ jobs:
action: stop
log_file_prefix: safe_test_logs_heavy_replicate_bench
platform: ubuntu-latest
build: true
build: true
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sn_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ serde = { version = "1.0.133", features = [ "derive"]}
sn_build_info = { path="../sn_build_info", version = "0.1.4" }
sn_client = { path = "../sn_client", version = "0.101.1" }
sn_transfers = { path = "../sn_transfers", version = "0.14.35" }
sn_registers = { path = "../sn_registers", version = "0.3.6" }
sn_logging = { path = "../sn_logging", version = "0.2.16" }
sn_peers_acquisition= { path="../sn_peers_acquisition", version = "0.2.0" }
sn_protocol = { path = "../sn_protocol", version = "0.10.4" }
Expand Down
28 changes: 19 additions & 9 deletions sn_cli/src/subcommands/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use clap::Subcommand;
use color_eyre::{eyre::WrapErr, Result, Section};
use sn_client::{Client, Error as ClientError, WalletClient};
use sn_protocol::storage::RegisterAddress;
use sn_registers::Permissions;
use sn_transfers::LocalWallet;
use std::path::Path;
use xor_name::XorName;
Expand All @@ -23,6 +24,11 @@ pub enum RegisterCmds {
/// This is used along with your public key to derive the address of the register
#[clap(name = "name", short = 'n')]
name: String,

/// Create the register with public write access.
/// By default only the owner can write to the register.
#[clap(name = "public", short = 'p')]
public: bool,
},
Edit {
/// The address of the register to edit.
Expand Down Expand Up @@ -56,8 +62,8 @@ pub(crate) async fn register_cmds(
verify_store: bool,
) -> Result<()> {
match cmds {
RegisterCmds::Create { name } => {
create_register(name, client, root_dir, verify_store).await?
RegisterCmds::Create { name, public } => {
create_register(name, public, client, root_dir, verify_store).await?
}
RegisterCmds::Edit {
address,
Expand All @@ -74,6 +80,7 @@ pub(crate) async fn register_cmds(

async fn create_register(
name: String,
public: bool,
client: &Client,
root_dir: &Path,
verify_store: bool,
Expand All @@ -88,21 +95,24 @@ async fn create_register(
let mut wallet_client = WalletClient::new(client.clone(), wallet);

let meta = XorName::from_content(name.as_bytes());
let perms = match public {
true => Permissions::new_anyone_can_write(),
false => Permissions::new_owner_only(),
};
let (register, storage_cost, royalties_fees) = client
.create_and_pay_for_register(meta, &mut wallet_client, verify_store)
.create_and_pay_for_register(meta, &mut wallet_client, verify_store, perms)
.await?;

if storage_cost.is_zero() {
println!(
"Register '{name}' already exists at {}!",
register.address().to_hex()
);
println!("Register '{name}' already exists!",);
} else {
println!(
"Successfully created register '{name}' at {} for {storage_cost:?} (royalties fees: {royalties_fees:?})!",
register.address().to_hex()
"Successfully created register '{name}' for {storage_cost:?} (royalties fees: {royalties_fees:?})!",
);
}

println!("REGISTER_ADDRESS={}", register.address().to_hex());

Ok(())
}

Expand Down
24 changes: 18 additions & 6 deletions sn_client/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use sn_protocol::{
},
NetworkAddress, PrettyPrintRecordKey,
};
use sn_registers::SignedRegister;
use sn_registers::{Permissions, SignedRegister};
use sn_transfers::{CashNote, CashNoteRedemption, MainPubkey, NanoTokens, Payment, SignedSpend};
use std::{
collections::{HashMap, HashSet},
Expand Down Expand Up @@ -342,10 +342,17 @@ impl Client {
address: XorName,
wallet_client: &mut WalletClient,
verify_store: bool,
perms: Permissions,
) -> Result<(ClientRegister, NanoTokens, NanoTokens)> {
info!("Instantiating a new Register replica with address {address:?}");
let (reg, mut total_cost, mut total_royalties) =
ClientRegister::create_online(self.clone(), address, wallet_client, false).await?;
let (reg, mut total_cost, mut total_royalties) = ClientRegister::create_online(
self.clone(),
address,
wallet_client,
false,
perms.clone(),
)
.await?;

debug!("{address:?} Created in theorryyyyy");
let reg_address = reg.address();
Expand All @@ -356,9 +363,14 @@ impl Client {
while !stored {
info!("Register not completely stored on the network yet. Retrying...");
// this verify store call here ensures we get the record from Quorum::all
let (reg, top_up_cost, royalties_top_up) =
ClientRegister::create_online(self.clone(), address, wallet_client, true)
.await?;
let (reg, top_up_cost, royalties_top_up) = ClientRegister::create_online(
self.clone(),
address,
wallet_client,
true,
perms.clone(),
)
.await?;
let reg_address = reg.address();

total_cost = total_cost
Expand Down
16 changes: 2 additions & 14 deletions sn_client/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,15 @@ impl ClientRegister {
Self::create_register(client, meta, Permissions::new_owner_only())
}

/// Create a new public Register (Anybody can write to it) and send it so the Network.
/// This will optionally verify the Register was stored on the network.
pub async fn create_public_online(
client: Client,
meta: XorName,
wallet_client: &mut WalletClient,
verify_store: bool,
) -> Result<Self> {
let mut reg = Self::create_register(client, meta, Permissions::new_anyone_can_write())?;
reg.sync(wallet_client, verify_store).await?;
Ok(reg)
}

/// Create a new Register and send it to the Network.
pub async fn create_online(
client: Client,
meta: XorName,
wallet_client: &mut WalletClient,
verify_store: bool,
perms: Permissions,
) -> Result<(Self, NanoTokens, NanoTokens)> {
let mut reg = Self::create_register(client, meta, Permissions::new_owner_only())?;
let mut reg = Self::create_register(client, meta, perms)?;
let (storage_cost, royalties_fees) = reg.sync(wallet_client, verify_store).await?;
Ok((reg, storage_cost, royalties_fees))
}
Expand Down
9 changes: 7 additions & 2 deletions sn_node/examples/registers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// permissions and limitations relating to use of the SAFE Network Software.

use sn_client::{Client, Error, WalletClient};
use sn_registers::RegisterAddress;
use sn_registers::{Permissions, RegisterAddress};
use sn_transfers::LocalWallet;
use xor_name::XorName;

Expand Down Expand Up @@ -77,7 +77,12 @@ async fn main() -> Result<()> {
Err(_) => {
println!("Register '{reg_nickname}' not found, creating it at {address}");
let (register, _cost, _royalties_fees) = client
.create_and_pay_for_register(meta, &mut wallet_client, true)
.create_and_pay_for_register(
meta,
&mut wallet_client,
true,
Permissions::new_anyone_can_write(),
)
.await?;

register
Expand Down
8 changes: 7 additions & 1 deletion sn_node/tests/data_with_churn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use sn_protocol::{
storage::{ChunkAddress, RegisterAddress, SpendAddress},
NetworkAddress,
};
use sn_registers::Permissions;
use sn_transfers::LocalWallet;
use sn_transfers::{CashNote, MainSecretKey, NanoTokens};
use std::{
Expand Down Expand Up @@ -349,7 +350,12 @@ fn create_registers_task(
sleep(delay).await;

match client
.create_and_pay_for_register(meta, &mut wallet_client, true)
.create_and_pay_for_register(
meta,
&mut wallet_client,
true,
Permissions::new_owner_only(),
)
.await
{
Ok(_) => content
Expand Down
15 changes: 13 additions & 2 deletions sn_node/tests/nodes_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use sn_protocol::safenode_proto::{
safe_node_client::SafeNodeClient, GossipsubSubscribeRequest, NodeEventsRequest,
TransferNotifsFilterRequest,
};
use sn_registers::Permissions;
use sn_transfers::{
CashNoteRedemption, LocalWallet, MainSecretKey, NanoTokens, NETWORK_ROYALTIES_PK,
};
Expand Down Expand Up @@ -84,7 +85,12 @@ async fn nodes_rewards_for_storing_registers() -> Result<()> {
let prev_rewards_balance = current_rewards_balance()?;

let (_register, storage_cost, _royalties_fees) = client
.create_and_pay_for_register(register_addr, &mut wallet_client, false)
.create_and_pay_for_register(
register_addr,
&mut wallet_client,
false,
Permissions::new_owner_only(),
)
.await?;
println!("Cost is {storage_cost:?}: {prev_rewards_balance:?}");

Expand Down Expand Up @@ -155,7 +161,12 @@ async fn nodes_rewards_for_register_notifs_over_gossipsub() -> Result<()> {

println!("Paying for random Register address {register_addr:?} ...");
let (_, storage_cost, royalties_fees) = client
.create_and_pay_for_register(register_addr, &mut wallet_client, false)
.create_and_pay_for_register(
register_addr,
&mut wallet_client,
false,
Permissions::new_owner_only(),
)
.await?;
println!("Random Register created, paid {storage_cost}/{royalties_fees}");

Expand Down
Loading

0 comments on commit bb3d801

Please sign in to comment.