switch from LP to credits and allow slots
This commit is contained in:
parent
13a00e2318
commit
704bdf414f
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -1,7 +1,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
@ -1184,7 +1183,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "detee-shared"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto.git?branch=surreal_brain_app#0b195b4589e4ec689af7ddca27dc051716ecee78"
|
||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto.git?branch=credits-v2#f344c171c5a8d7ae8cad1628396e6b3a1af0f1ba"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"prost",
|
||||
|
@ -36,7 +36,7 @@ tokio-retry = "0.3.0"
|
||||
detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch = "hratls", features=["hratls", "qvl"] }
|
||||
shadow-rs = { version = "1.1.1", features = ["metadata"] }
|
||||
|
||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "surreal_brain_app" }
|
||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "credits-v2" }
|
||||
# detee-shared = { path = "../detee-shared" }
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -160,7 +160,7 @@ fn clap_cmd() -> Command {
|
||||
.help("for how many hours should the app run")
|
||||
.default_value("1")
|
||||
.value_parser(clap::value_parser!(u64).range(1..5000))
|
||||
.long_help("How long should the app run for so it locks up LP accordingly")
|
||||
.long_help("How long should the app run for so it locks up credits accordingly")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("price")
|
||||
@ -347,16 +347,16 @@ fn clap_cmd() -> Command {
|
||||
.arg(
|
||||
Arg::new("memory")
|
||||
.long("memory")
|
||||
.default_value("1000")
|
||||
.value_parser(clap::value_parser!(u32).range(800..123000))
|
||||
.help("memory in MB")
|
||||
.default_value("1")
|
||||
.value_parser(clap::value_parser!(u32).range(1..500))
|
||||
.help("memory in GiB")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("disk")
|
||||
.long("disk")
|
||||
.default_value("10")
|
||||
.value_parser(clap::value_parser!(u32).range(5..500))
|
||||
.help("disk size in GB")
|
||||
.help("disk size in GiB")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("distribution")
|
||||
@ -375,8 +375,8 @@ fn clap_cmd() -> Command {
|
||||
.arg(
|
||||
Arg::new("price")
|
||||
.long("price")
|
||||
.help("price per unit per minute; check docs")
|
||||
.default_value("20000")
|
||||
.help("maxium accepted price per unit per minute")
|
||||
.default_value("4000")
|
||||
.value_parser(clap::value_parser!(u64).range(1..50000000))
|
||||
)
|
||||
.arg(
|
||||
@ -437,7 +437,7 @@ fn clap_cmd() -> Command {
|
||||
.long_about("Allows you to update the hardware or the lifetime".to_string() +
|
||||
"\nAny hardware modifiations will restart the VM." +
|
||||
"\nChanging the lifetime of a VM will not restart." +
|
||||
"\nIf changing the lifetime to a higher value, LP will locked accordingly.")
|
||||
"\nIf changing the lifetime to a higher value, credits will locked accordingly.")
|
||||
.arg(
|
||||
Arg::new("uuid")
|
||||
.help("supply the uuid of the VM you wish to upgrade")
|
||||
@ -537,7 +537,7 @@ fn clap_cmd() -> Command {
|
||||
.arg(
|
||||
Arg::new("escrow")
|
||||
.long("escrow")
|
||||
.help("At least 5000 LP is required as escrow")
|
||||
.help("At least 5000 credits is required as escrow")
|
||||
.long_help("Escrow is used by node operators to guarantee quality.".to_owned() +
|
||||
"\nBefore adding escrow, make sure you booted a node under your account." +
|
||||
"\nWhen all your nodes got decomissioned, your escrow gets automatically returned.")
|
||||
|
@ -36,10 +36,10 @@ impl super::HumanOutput for AccountData {
|
||||
}
|
||||
if !self.wallet_path.is_empty() {
|
||||
println!("The address of your DeTEE wallet is {}", self.wallet_address);
|
||||
println!("The balance of your account is {} LP", self.account_balance);
|
||||
println!("The balance of your account is {} credits", self.account_balance);
|
||||
if self.locked_funds != 0.0 {
|
||||
println!(
|
||||
"WARNING! {} LP is temporary locked, waiting for a Contract.",
|
||||
"WARNING! {} credits is temporary locked, waiting for a Contract.",
|
||||
self.locked_funds
|
||||
);
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ pub async fn kick_contract(contract_uuid: String, reason: String) -> Result<u64,
|
||||
})?)
|
||||
.await?
|
||||
.into_inner()
|
||||
.nano_lp)
|
||||
.nano_credits)
|
||||
}
|
||||
|
||||
pub async fn ban_user(user_wallet: String) -> Result<(), Error> {
|
||||
|
@ -35,7 +35,7 @@ pub fn register(escrow: u64, email: String) -> Result<crate::SimpleOutput, grpc:
|
||||
impl crate::HumanOutput for grpc::proto::InspectOperatorResp {
|
||||
fn human_cli_print(&self) {
|
||||
if let Some(op) = &self.operator {
|
||||
println!("The operator {} supplies {} nanoLP as escrow,", op.pubkey, op.escrow,);
|
||||
println!("The operator {} supplies {} nanocredits as escrow,", op.pubkey, op.escrow,);
|
||||
println!(
|
||||
"has {} app servers, {} VM servers, and {} total reports for all servers.",
|
||||
op.app_nodes, op.vm_nodes, op.reports
|
||||
@ -77,7 +77,7 @@ pub fn print_operators() -> Result<Vec<grpc::proto::ListOperatorsResp>, grpc::Er
|
||||
pub fn kick(contract_uuid: String, reason: String) -> Result<crate::SimpleOutput, grpc::Error> {
|
||||
let nano_lp = block_on(grpc::kick_contract(contract_uuid, reason))?;
|
||||
Ok(crate::SimpleOutput::from(
|
||||
format!("Successfully terminated contract. Refunded {} nanoLP.", nano_lp).as_str(),
|
||||
format!("Successfully terminated contract. Refunded {} nanocredits.", nano_lp).as_str(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ impl crate::HumanOutput for AppContract {
|
||||
"The App has {} vCPUS, {}MB of memory and a disk of {} GB.",
|
||||
app_resource.vcpus, app_resource.memory_mb, app_resource.disk_size_gb
|
||||
);
|
||||
println!("You have locked {} nanoLP in the contract, that get collected at a rate of {} nanoLP per minute.",
|
||||
println!("You have locked {} nanocredits in the contract, that get collected at a rate of {} nanocredits per minute.",
|
||||
self.locked_nano, self.nano_per_minute);
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ pub struct AppContract {
|
||||
pub memory_mb: u32,
|
||||
#[tabled(rename = "Disk (GB)")]
|
||||
pub disk_size_gb: u32,
|
||||
#[tabled(rename = "LP/h")]
|
||||
#[tabled(rename = "credits/h")]
|
||||
pub cost_h: String,
|
||||
#[tabled(rename = "time left", display_with = "display_mins")]
|
||||
pub time_left: u64,
|
||||
@ -268,7 +268,7 @@ impl From<AppNodeListResp> for TabledAppNode {
|
||||
operator: brain_node.operator,
|
||||
location: brain_node.city + ", " + &brain_node.region + ", " + &brain_node.country,
|
||||
public_ip: brain_node.ip,
|
||||
price: format!("{} nanoLP/min", brain_node.price),
|
||||
price: format!("{} nanocredits/min", brain_node.price),
|
||||
reports: brain_node.reports.len(),
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +69,8 @@ fn handle_vm_deploy(matches: &ArgMatches) -> Result<snp::VmSshArgs, Box<dyn Erro
|
||||
ipv4,
|
||||
public_ipv6: false,
|
||||
vcpus: *matches.get_one::<u32>("vcpus").unwrap(),
|
||||
memory_mb: *matches.get_one::<u32>("memory").unwrap(),
|
||||
disk_size_gb: *matches.get_one::<u32>("disk").unwrap(),
|
||||
memory_gib: *matches.get_one::<u32>("memory").unwrap(),
|
||||
disk_size_gib: *matches.get_one::<u32>("disk").unwrap(),
|
||||
dtrfs: None,
|
||||
hours: *matches.get_one::<u32>("hours").unwrap(),
|
||||
price: *matches.get_one::<u64>("price").unwrap(),
|
||||
|
@ -4,8 +4,7 @@ use super::{
|
||||
grpc::{self, proto},
|
||||
injector, Distro, Dtrfs, Error, VmSshArgs, DEFAULT_ARCHLINUX, DEFAULT_DTRFS,
|
||||
};
|
||||
use crate::config::Config;
|
||||
use crate::utils::block_on;
|
||||
use crate::{config::Config, utils::block_on};
|
||||
use log::{debug, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -51,8 +50,8 @@ pub struct Request {
|
||||
pub ipv4: IPv4Config,
|
||||
pub public_ipv6: bool,
|
||||
pub vcpus: u32,
|
||||
pub memory_mb: u32,
|
||||
pub disk_size_gb: u32,
|
||||
pub memory_gib: u32,
|
||||
pub disk_size_gib: u32,
|
||||
pub dtrfs: Option<Dtrfs>,
|
||||
pub distro: Option<Distro>,
|
||||
}
|
||||
@ -70,8 +69,8 @@ impl Request {
|
||||
}
|
||||
|
||||
pub fn deploy(&self) -> Result<VmSshArgs, Error> {
|
||||
let (node_ip, new_vm_resp) = self.send_vm_request()?;
|
||||
info!("Got confirmation from the node {node_ip} that VM started.");
|
||||
let (vcpus, new_vm_resp) = self.calculate_and_send_request()?;
|
||||
info!("Got confirmation from the node that the VM started.");
|
||||
debug!("IPs and ports assigned by node are: {new_vm_resp:#?}");
|
||||
if !new_vm_resp.error.is_empty() {
|
||||
return Err(Error::Node(new_vm_resp.error));
|
||||
@ -83,7 +82,7 @@ impl Request {
|
||||
let args = new_vm_resp.args.ok_or(Error::NoMeasurement)?;
|
||||
let measurement_args = injector::Args {
|
||||
uuid: new_vm_resp.uuid.clone(),
|
||||
vcpus: self.vcpus,
|
||||
vcpus,
|
||||
kernel: kernel_sha,
|
||||
initrd: dtrfs_sha,
|
||||
args: args.clone(),
|
||||
@ -107,10 +106,107 @@ impl Request {
|
||||
Ok(ssh_args)
|
||||
}
|
||||
|
||||
// returns node IP and data regarding the new VM
|
||||
fn send_vm_request(&self) -> Result<(String, proto::NewVmResp), Error> {
|
||||
let admin_pubkey = Config::get_detee_wallet()?;
|
||||
let node = self.get_node()?;
|
||||
/// returns number of vCPUs and response from the daemon
|
||||
fn calculate_and_send_request(&self) -> Result<(u32, proto::NewVmResp), Error> {
|
||||
let new_vm_req = self.get_cheapest_offer()?;
|
||||
let vcpus = new_vm_req.vcpus;
|
||||
|
||||
eprintln!(
|
||||
"Locking {} credits for {} hours of the following HW spec: {} vCPUs, {} MiB Mem, {} MiB Disk",
|
||||
new_vm_req.locked_nano as f64 / 1_000_000_000_f64,
|
||||
self.hours,
|
||||
new_vm_req.vcpus,
|
||||
new_vm_req.memory_mib,
|
||||
new_vm_req.disk_size_mib
|
||||
);
|
||||
|
||||
// eprint!(
|
||||
// "Node price: {}/unit/minute. Total Units for hardware requested: {}. ",
|
||||
// node_price as f64 / 1_000_000_000.0,
|
||||
// total_units,
|
||||
// );
|
||||
// eprintln!(
|
||||
// "Locking {} LP (offering the VM for {} hours).",
|
||||
// locked_nano as f64 / 1_000_000_000.0,
|
||||
// hours
|
||||
// );
|
||||
|
||||
let new_vm_resp = block_on(grpc::create_vm(new_vm_req))?;
|
||||
if !new_vm_resp.error.is_empty() {
|
||||
return Err(Error::Node(new_vm_resp.error));
|
||||
}
|
||||
Ok((vcpus, new_vm_resp))
|
||||
}
|
||||
|
||||
fn get_cheapest_offer(&self) -> Result<proto::NewVmReq, Error> {
|
||||
let (free_ports, offers_ipv4) = match &self.ipv4 {
|
||||
IPv4Config::PublishPorts(vec) => (vec.len() as u32, false),
|
||||
IPv4Config::PublicIPv4 => (0, true),
|
||||
};
|
||||
let filters = proto::VmNodeFilters {
|
||||
free_ports,
|
||||
offers_ipv4,
|
||||
offers_ipv6: self.public_ipv6,
|
||||
vcpus: self.vcpus,
|
||||
memory_mib: self.memory_gib * 1024,
|
||||
storage_mib: self.disk_size_gib * 1024,
|
||||
country: self.location.country.clone().unwrap_or_default(),
|
||||
region: self.location.region.clone().unwrap_or_default(),
|
||||
city: self.location.city.clone().unwrap_or_default(),
|
||||
ip: self.location.node_ip.clone().unwrap_or_default(),
|
||||
node_pubkey: String::new(),
|
||||
};
|
||||
let node_list = match block_on(grpc::get_node_list(filters)) {
|
||||
Ok(node_list) => Ok(node_list),
|
||||
Err(e) => {
|
||||
log::error!("Coult not get node from brain: {e:?}");
|
||||
Err(Error::NoValidNodeFound)
|
||||
}
|
||||
}?;
|
||||
|
||||
let mut node_list_iter = node_list.iter();
|
||||
let mut final_request =
|
||||
self.calculate_vm_request(Config::get_detee_wallet()?, node_list_iter.next().unwrap());
|
||||
while let Some(node) = node_list_iter.next() {
|
||||
let new_vm_req = self.calculate_vm_request(Config::get_detee_wallet()?, node);
|
||||
if new_vm_req.locked_nano < final_request.locked_nano {
|
||||
final_request = new_vm_req;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(final_request)
|
||||
}
|
||||
|
||||
fn calculate_vm_request(
|
||||
&self,
|
||||
admin_pubkey: String,
|
||||
node: &proto::VmNodeListResp,
|
||||
) -> proto::NewVmReq {
|
||||
let memory_per_cpu = node.memory_mib / node.vcpus;
|
||||
let disk_per_cpu = node.disk_mib / node.vcpus;
|
||||
let mut vcpus = self.vcpus;
|
||||
if vcpus < (self.memory_gib * 1024).div_ceil(memory_per_cpu as u32) {
|
||||
vcpus = (self.memory_gib * 1024).div_ceil(memory_per_cpu as u32);
|
||||
}
|
||||
if vcpus < (self.disk_size_gib * 1024).div_ceil(disk_per_cpu as u32) {
|
||||
vcpus = (self.disk_size_gib * 1024).div_ceil(disk_per_cpu as u32);
|
||||
}
|
||||
|
||||
let memory_mib = vcpus * memory_per_cpu as u32;
|
||||
let disk_size_mib = vcpus * disk_per_cpu as u32;
|
||||
|
||||
let nanocredits = super::calculate_nanocredits(
|
||||
vcpus,
|
||||
memory_mib,
|
||||
disk_size_mib,
|
||||
match self.ipv4 {
|
||||
IPv4Config::PublishPorts(_) => false,
|
||||
IPv4Config::PublicIPv4 => true,
|
||||
},
|
||||
self.hours,
|
||||
node.price,
|
||||
);
|
||||
|
||||
let (extra_ports, public_ipv4): (Vec<u32>, bool) = match &self.ipv4 {
|
||||
IPv4Config::PublishPorts(vec) => (vec.to_vec(), false),
|
||||
IPv4Config::PublicIPv4 => (Vec::new(), true),
|
||||
@ -124,63 +220,31 @@ impl Request {
|
||||
DEFAULT_DTRFS.dtrfs_sha.clone(),
|
||||
),
|
||||
};
|
||||
let locked_nano = super::calculate_nanolp(
|
||||
self.vcpus,
|
||||
self.memory_mb,
|
||||
self.disk_size_gb,
|
||||
public_ipv4,
|
||||
self.hours,
|
||||
self.price,
|
||||
);
|
||||
|
||||
let brain_req = proto::NewVmReq {
|
||||
uuid: String::new(),
|
||||
hostname: self.hostname.clone(),
|
||||
admin_pubkey,
|
||||
node_pubkey: node.node_pubkey,
|
||||
node_pubkey: node.node_pubkey.clone(),
|
||||
extra_ports,
|
||||
public_ipv4,
|
||||
public_ipv6: self.public_ipv6,
|
||||
disk_size_gb: self.disk_size_gb,
|
||||
vcpus: self.vcpus,
|
||||
memory_mb: self.memory_mb,
|
||||
disk_size_mib,
|
||||
vcpus,
|
||||
memory_mib,
|
||||
kernel_url,
|
||||
kernel_sha,
|
||||
dtrfs_url,
|
||||
dtrfs_sha,
|
||||
price_per_unit: self.price,
|
||||
locked_nano,
|
||||
price_per_unit: node.price,
|
||||
locked_nano: nanocredits,
|
||||
};
|
||||
let new_vm_resp = block_on(grpc::create_vm(brain_req))?;
|
||||
if !new_vm_resp.error.is_empty() {
|
||||
return Err(Error::Node(new_vm_resp.error));
|
||||
}
|
||||
Ok((node.ip, new_vm_resp))
|
||||
}
|
||||
|
||||
pub fn get_node(&self) -> Result<proto::VmNodeListResp, Error> {
|
||||
let (free_ports, offers_ipv4) = match &self.ipv4 {
|
||||
IPv4Config::PublishPorts(vec) => (vec.len() as u32, false),
|
||||
IPv4Config::PublicIPv4 => (0, true),
|
||||
};
|
||||
let filters = proto::VmNodeFilters {
|
||||
free_ports,
|
||||
offers_ipv4,
|
||||
offers_ipv6: self.public_ipv6,
|
||||
vcpus: self.vcpus,
|
||||
memory_mb: self.memory_mb,
|
||||
storage_gb: self.disk_size_gb,
|
||||
country: self.location.country.clone().unwrap_or_default(),
|
||||
region: self.location.region.clone().unwrap_or_default(),
|
||||
city: self.location.city.clone().unwrap_or_default(),
|
||||
ip: self.location.node_ip.clone().unwrap_or_default(),
|
||||
node_pubkey: String::new(),
|
||||
};
|
||||
match block_on(grpc::get_one_node(filters)) {
|
||||
Ok(node) => Ok(node),
|
||||
Err(e) => {
|
||||
log::error!("Coult not get node from brain: {e:?}");
|
||||
Err(Error::NoValidNodeFound)
|
||||
}
|
||||
}
|
||||
debug!(
|
||||
"Node {} can offer the VM at {} nanocredits for {} hours. Spec: {} vCPUs, {} MiB mem, {} MiB disk.",
|
||||
node.ip, brain_req.locked_nano, self.hours, brain_req.vcpus, brain_req.memory_mib, brain_req.disk_size_mib
|
||||
);
|
||||
|
||||
brain_req
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ impl crate::HumanOutput for VmContract {
|
||||
"The VM has {} vCPUS, {}MB of memory and a disk of {} GB.",
|
||||
self.vcpus, self.memory_mb, self.disk_size_gb
|
||||
);
|
||||
println!("You have locked {} nanoLP in the contract, that get collected at a rate of {} nanoLP per minute.",
|
||||
println!("You have locked {} nanocredits in the contract, that get collected at a rate of {} nanocredits per minute.",
|
||||
self.locked_nano, self.nano_per_minute);
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ pub async fn extend_vm(uuid: String, admin_pubkey: String, locked_nano: u64) ->
|
||||
Ok(confirmation) => {
|
||||
log::debug!("VM contract extension confirmation: {confirmation:?}");
|
||||
log::info!(
|
||||
"VM contract got updated. It now has {} LP locked for the VM.",
|
||||
"VM contract got updated. It now has {} credits locked for the VM.",
|
||||
locked_nano as f64 / 1_000_000_000.0
|
||||
);
|
||||
}
|
||||
|
@ -6,11 +6,10 @@ pub mod grpc;
|
||||
mod injector;
|
||||
pub mod update;
|
||||
|
||||
use crate::utils::block_on;
|
||||
use crate::utils::shorten_string;
|
||||
use crate::{
|
||||
config::{self, Config},
|
||||
snp,
|
||||
utils::{block_on, shorten_string, display_mib_or_gib},
|
||||
};
|
||||
use grpc::proto;
|
||||
use lazy_static::lazy_static;
|
||||
@ -157,12 +156,12 @@ pub struct VmContract {
|
||||
pub uuid: String,
|
||||
pub hostname: String,
|
||||
#[tabled(rename = "Cores")]
|
||||
pub vcpus: u32,
|
||||
#[tabled(rename = "Mem (MB)")]
|
||||
pub mem: u32,
|
||||
#[tabled(rename = "Disk")]
|
||||
pub disk: u32,
|
||||
#[tabled(rename = "LP/h")]
|
||||
pub vcpus: u64,
|
||||
#[tabled(rename = "Mem", display_with = "display_mib_or_gib")]
|
||||
pub mem: u64,
|
||||
#[tabled(rename = "Disk", display_with = "display_mib_or_gib")]
|
||||
pub disk: u64,
|
||||
#[tabled(rename = "credits/h")]
|
||||
pub cost_h: f64,
|
||||
#[tabled(rename = "time left", display_with = "display_mins")]
|
||||
pub time_left: u64,
|
||||
@ -189,9 +188,9 @@ impl From<proto::VmContract> for VmContract {
|
||||
Self {
|
||||
uuid: brain_contract.uuid,
|
||||
hostname: brain_contract.hostname,
|
||||
vcpus: brain_contract.vcpus,
|
||||
mem: brain_contract.memory_mb,
|
||||
disk: brain_contract.disk_size_gb,
|
||||
vcpus: brain_contract.vcpus as u64,
|
||||
mem: brain_contract.memory_mb as u64,
|
||||
disk: brain_contract.disk_size_gb as u64,
|
||||
location: brain_contract.location,
|
||||
cost_h: (brain_contract.nano_per_minute * 60) as f64 / 1_000_000_000.0,
|
||||
time_left: brain_contract.locked_nano / brain_contract.nano_per_minute,
|
||||
@ -201,10 +200,16 @@ impl From<proto::VmContract> for VmContract {
|
||||
|
||||
#[derive(Tabled, Debug, Serialize, Deserialize)]
|
||||
pub struct TabledVmNode {
|
||||
#[tabled(rename = "Operator")]
|
||||
#[tabled(rename = "Operator", display_with = "shorten_string")]
|
||||
pub operator: String,
|
||||
#[tabled(rename = "City, Region, Country")]
|
||||
pub location: String,
|
||||
#[tabled(rename = "Cores")]
|
||||
pub vcpus: u64,
|
||||
#[tabled(rename = "Mem", display_with = "display_mib_or_gib")]
|
||||
pub memory_mib: u64,
|
||||
#[tabled(rename = "Disk", display_with = "display_mib_or_gib")]
|
||||
pub disk_mib: u64,
|
||||
#[tabled(rename = "IP")]
|
||||
pub public_ip: String,
|
||||
#[tabled(rename = "Price per unit")]
|
||||
@ -219,8 +224,11 @@ impl From<proto::VmNodeListResp> for TabledVmNode {
|
||||
operator: brain_node.operator,
|
||||
location: brain_node.city + ", " + &brain_node.region + ", " + &brain_node.country,
|
||||
public_ip: brain_node.ip,
|
||||
price: format!("{} nanoLP/min", brain_node.price),
|
||||
price: format!("{} nano/min", brain_node.price),
|
||||
reports: brain_node.reports.len(),
|
||||
vcpus: brain_node.vcpus,
|
||||
memory_mib: brain_node.memory_mib,
|
||||
disk_mib: brain_node.disk_mib,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,10 +348,10 @@ pub fn inspect_node(ip: String) -> Result<proto::VmNodeListResp, Error> {
|
||||
Ok(block_on(grpc::get_one_node(req))?)
|
||||
}
|
||||
|
||||
pub fn calculate_nanolp(
|
||||
pub fn calculate_nanocredits(
|
||||
vcpus: u32,
|
||||
memory_mb: u32,
|
||||
disk_size_gb: u32,
|
||||
disk_size_mib: u32,
|
||||
public_ipv4: bool,
|
||||
hours: u32,
|
||||
node_price: u64,
|
||||
@ -351,19 +359,9 @@ pub fn calculate_nanolp(
|
||||
// this calculation needs to match the calculation of the network
|
||||
let total_units = (vcpus as u64 * 10)
|
||||
+ ((memory_mb + 256) as u64 / 200)
|
||||
+ (disk_size_gb as u64 / 10)
|
||||
+ (disk_size_mib as u64 / 1024 / 10)
|
||||
+ (public_ipv4 as u64 * 10);
|
||||
let locked_nano = hours as u64 * 60 * total_units * node_price;
|
||||
eprint!(
|
||||
"Node price: {}/unit/minute. Total Units for hardware requested: {}. ",
|
||||
node_price as f64 / 1_000_000_000.0,
|
||||
total_units,
|
||||
);
|
||||
eprintln!(
|
||||
"Locking {} LP (offering the VM for {} hours).",
|
||||
locked_nano as f64 / 1_000_000_000.0,
|
||||
hours
|
||||
);
|
||||
locked_nano
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@ use log::{debug, info};
|
||||
pub struct Request {
|
||||
hostname: String,
|
||||
vcpus: u32,
|
||||
memory_mb: u32,
|
||||
disk_size_gb: u32,
|
||||
memory_mib: u32,
|
||||
disk_size_mib: u32,
|
||||
dtrfs: Option<Dtrfs>,
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ impl Request {
|
||||
Some(Dtrfs::load_from_file(path)?)
|
||||
}
|
||||
};
|
||||
let req = Self { hostname, vcpus, memory_mb, disk_size_gb, dtrfs };
|
||||
let req = Self { hostname, vcpus, memory_mib: memory_mb, disk_size_mib: disk_size_gb, dtrfs };
|
||||
if req == Self::default() {
|
||||
log::info!("Skipping hardware upgrade (no arguments specified).");
|
||||
return Ok(());
|
||||
@ -90,9 +90,9 @@ impl Request {
|
||||
uuid: uuid.to_string(),
|
||||
hostname: self.hostname.clone(),
|
||||
admin_pubkey: Config::get_detee_wallet()?,
|
||||
disk_size_gb: self.disk_size_gb,
|
||||
disk_size_mib: self.disk_size_mib * 1024,
|
||||
vcpus: self.vcpus,
|
||||
memory_mb: self.memory_mb,
|
||||
memory_mib: self.memory_mib * 1024,
|
||||
kernel_url,
|
||||
kernel_sha,
|
||||
dtrfs_url,
|
||||
|
@ -45,6 +45,14 @@ pub fn shorten_string(my_string: &String) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_mib_or_gib(value: &u64) -> String {
|
||||
if *value > 1024 {
|
||||
format!("{}G", value / 1024)
|
||||
} else {
|
||||
format!("{}M", value)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! call_with_follow_redirect {
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user