add support for multiple offers per node
This commit is contained in:
parent
f7df59e068
commit
6d2b5ed377
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1184,7 +1184,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "detee-shared"
|
name = "detee-shared"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto.git?branch=credits_app#01e93d3a2e4502c0e8e72026e8a1c55810961815"
|
source = "git+ssh://git@gitea.detee.cloud/testnet/proto.git?branch=offers#4753a17fa29393b3f99b6dfcdcec48d935e6ebd9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"prost",
|
"prost",
|
||||||
|
@ -37,7 +37,7 @@ detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch
|
|||||||
shadow-rs = { version = "1.1.1", features = ["metadata"] }
|
shadow-rs = { version = "1.1.1", features = ["metadata"] }
|
||||||
serde_default_utils = "0.3.1"
|
serde_default_utils = "0.3.1"
|
||||||
|
|
||||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "credits_app" }
|
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "offers" }
|
||||||
# detee-shared = { path = "../detee-shared" }
|
# detee-shared = { path = "../detee-shared" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use std::u64::MAX;
|
||||||
|
|
||||||
use super::grpc::{self, proto};
|
use super::grpc::{self, proto};
|
||||||
use super::{injector, Distro, Dtrfs, Error, VmSshArgs, DEFAULT_ARCHLINUX, DEFAULT_DTRFS};
|
use super::{injector, Distro, Dtrfs, Error, VmSshArgs, DEFAULT_ARCHLINUX, DEFAULT_DTRFS};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
@ -138,27 +140,39 @@ impl Request {
|
|||||||
}?;
|
}?;
|
||||||
|
|
||||||
let mut node_list_iter = node_list.iter();
|
let mut node_list_iter = node_list.iter();
|
||||||
let mut final_request = self.calculate_vm_request(
|
let mut final_request: proto::NewVmReq =
|
||||||
Config::get_detee_wallet()?,
|
proto::NewVmReq { locked_nano: MAX, ..Default::default() };
|
||||||
node_list_iter.next().ok_or(Error::NoValidNodeFound)?,
|
|
||||||
);
|
|
||||||
while let Some(node) = node_list_iter.next() {
|
while let Some(node) = node_list_iter.next() {
|
||||||
let new_vm_req = self.calculate_vm_request(Config::get_detee_wallet()?, node);
|
for offer in node.offers.iter() {
|
||||||
if new_vm_req.locked_nano < final_request.locked_nano {
|
if let Some(new_vm_req) =
|
||||||
final_request = new_vm_req;
|
self.calculate_vm_request(Config::get_detee_wallet()?, &node.node_pubkey, offer)
|
||||||
|
{
|
||||||
|
if new_vm_req.locked_nano < final_request.locked_nano {
|
||||||
|
final_request = new_vm_req;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if final_request.node_pubkey.is_empty() {
|
||||||
|
return Err(Error::NoValidNodeFound);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(final_request)
|
Ok(final_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_vm_request(
|
fn calculate_vm_request(
|
||||||
&self,
|
&self,
|
||||||
admin_pubkey: String,
|
admin_pubkey: String,
|
||||||
node: &proto::VmNodeListResp,
|
node_pubkey: &str,
|
||||||
) -> proto::NewVmReq {
|
offer: &proto::VmNodeOffer,
|
||||||
let memory_per_cpu = node.memory_mib / node.vcpus;
|
) -> Option<proto::NewVmReq> {
|
||||||
let disk_per_cpu = node.disk_mib / node.vcpus;
|
if offer.vcpus == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let memory_per_cpu = offer.memory_mib / offer.vcpus;
|
||||||
|
let disk_per_cpu = offer.disk_mib / offer.vcpus;
|
||||||
let mut vcpus = self.vcpus;
|
let mut vcpus = self.vcpus;
|
||||||
if vcpus < (self.memory_gib * 1024).div_ceil(memory_per_cpu as u32) {
|
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);
|
vcpus = (self.memory_gib * 1024).div_ceil(memory_per_cpu as u32);
|
||||||
@ -170,6 +184,13 @@ impl Request {
|
|||||||
let memory_mib = vcpus * memory_per_cpu as u32;
|
let memory_mib = vcpus * memory_per_cpu as u32;
|
||||||
let disk_size_mib = vcpus * disk_per_cpu as u32;
|
let disk_size_mib = vcpus * disk_per_cpu as u32;
|
||||||
|
|
||||||
|
if memory_mib > offer.memory_mib as u32
|
||||||
|
|| disk_size_mib > offer.disk_mib as u32
|
||||||
|
|| vcpus > offer.vcpus as u32
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let (extra_ports, public_ipv4): (Vec<u32>, bool) = match &self.ipv4 {
|
let (extra_ports, public_ipv4): (Vec<u32>, bool) = match &self.ipv4 {
|
||||||
IPv4Config::PublishPorts(vec) => (vec.to_vec(), false),
|
IPv4Config::PublishPorts(vec) => (vec.to_vec(), false),
|
||||||
IPv4Config::PublicIPv4 => (Vec::new(), true),
|
IPv4Config::PublicIPv4 => (Vec::new(), true),
|
||||||
@ -190,14 +211,14 @@ impl Request {
|
|||||||
disk_size_mib,
|
disk_size_mib,
|
||||||
public_ipv4,
|
public_ipv4,
|
||||||
self.hours,
|
self.hours,
|
||||||
node.price,
|
offer.price,
|
||||||
);
|
);
|
||||||
|
|
||||||
let brain_req = proto::NewVmReq {
|
let brain_req = proto::NewVmReq {
|
||||||
uuid: String::new(),
|
uuid: String::new(),
|
||||||
hostname: self.hostname.clone(),
|
hostname: self.hostname.clone(),
|
||||||
admin_pubkey,
|
admin_pubkey,
|
||||||
node_pubkey: node.node_pubkey.clone(),
|
node_pubkey: node_pubkey.to_string(),
|
||||||
extra_ports,
|
extra_ports,
|
||||||
public_ipv4,
|
public_ipv4,
|
||||||
public_ipv6: self.public_ipv6,
|
public_ipv6: self.public_ipv6,
|
||||||
@ -208,15 +229,15 @@ impl Request {
|
|||||||
kernel_sha,
|
kernel_sha,
|
||||||
dtrfs_url,
|
dtrfs_url,
|
||||||
dtrfs_sha,
|
dtrfs_sha,
|
||||||
price_per_unit: node.price,
|
price_per_unit: offer.price,
|
||||||
locked_nano: nanocredits,
|
locked_nano: nanocredits,
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Node {} can offer the VM at {} nanocredits for {} hours. Spec: {} vCPUs, {} MiB mem, {} MiB disk.",
|
"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
|
node_pubkey, brain_req.locked_nano, self.hours, brain_req.vcpus, brain_req.memory_mib, brain_req.disk_size_mib
|
||||||
);
|
);
|
||||||
|
|
||||||
brain_req
|
Some(brain_req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,15 @@ impl crate::HumanOutput for VmNodeListResp {
|
|||||||
"This node is located in the city {}, within the region of {}, in {}",
|
"This node is located in the city {}, within the region of {}, in {}",
|
||||||
self.city, self.region, self.country
|
self.city, self.region, self.country
|
||||||
);
|
);
|
||||||
println!("The price multiplier for the node is {}.", self.price);
|
if self.offers.len() > 0 {
|
||||||
|
println!("The node is offering the following offers:");
|
||||||
|
}
|
||||||
|
for offer in self.offers.iter() {
|
||||||
|
println!(
|
||||||
|
" - {} vcpus, {} MiB of memory, {} MiB of storage at a price per unit of {}",
|
||||||
|
offer.vcpus, offer.memory_mib, offer.disk_mib, offer.price
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,17 +248,27 @@ pub struct TabledVmNode {
|
|||||||
|
|
||||||
impl From<proto::VmNodeListResp> for TabledVmNode {
|
impl From<proto::VmNodeListResp> for TabledVmNode {
|
||||||
fn from(brain_node: proto::VmNodeListResp) -> Self {
|
fn from(brain_node: proto::VmNodeListResp) -> Self {
|
||||||
|
let (mut vcpus, mut memory_mib, mut disk_mib): (u64, u64, u64) = (0, 0, 0);
|
||||||
|
let mut price = 0;
|
||||||
|
for offer in brain_node.offers.iter() {
|
||||||
|
vcpus = vcpus.saturating_add(offer.vcpus);
|
||||||
|
memory_mib = memory_mib.saturating_add(offer.memory_mib);
|
||||||
|
disk_mib = disk_mib.saturating_add(offer.disk_mib);
|
||||||
|
if offer.price > price {
|
||||||
|
price = offer.price;
|
||||||
|
}
|
||||||
|
}
|
||||||
Self {
|
Self {
|
||||||
operator: brain_node.operator,
|
operator: brain_node.operator,
|
||||||
location: brain_node.city + ", " + &brain_node.region + ", " + &brain_node.country,
|
location: brain_node.city + ", " + &brain_node.region + ", " + &brain_node.country,
|
||||||
main_ip: brain_node.ip,
|
main_ip: brain_node.ip,
|
||||||
price: format!("{} nano/min", brain_node.price),
|
price: format!("{} nano/min", price),
|
||||||
reports: brain_node.reports.len(),
|
reports: brain_node.reports.len(),
|
||||||
vcpus: brain_node.vcpus,
|
|
||||||
memory_mib: brain_node.memory_mib,
|
|
||||||
disk_mib: brain_node.disk_mib,
|
|
||||||
public_ipv4: brain_node.public_ipv4,
|
public_ipv4: brain_node.public_ipv4,
|
||||||
public_ipv6: brain_node.public_ipv6,
|
public_ipv6: brain_node.public_ipv6,
|
||||||
|
vcpus,
|
||||||
|
memory_mib,
|
||||||
|
disk_mib,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,31 +436,36 @@ pub fn print_node_offers(location: Location) -> Result<Vec<NodeOffer>, Error> {
|
|||||||
let node_list = block_on(grpc::get_node_list(req))?;
|
let node_list = block_on(grpc::get_node_list(req))?;
|
||||||
let mut offers: Vec<NodeOffer> = Vec::new();
|
let mut offers: Vec<NodeOffer> = Vec::new();
|
||||||
for node in node_list.iter() {
|
for node in node_list.iter() {
|
||||||
let mem_per_cpu = node.memory_mib / node.vcpus;
|
for offer in node.offers.iter() {
|
||||||
let disk_per_cpu = node.disk_mib / node.vcpus;
|
if offer.vcpus == 0 || offer.memory_mib == 0 || offer.disk_mib == 0 {
|
||||||
for i in 1..node.vcpus {
|
continue;
|
||||||
let price_per_month = calculate_nanocredits(
|
}
|
||||||
(node.vcpus * i) as u32,
|
let mem_per_cpu = offer.memory_mib / offer.vcpus;
|
||||||
(mem_per_cpu * i) as u32,
|
let disk_per_cpu = offer.disk_mib / offer.vcpus;
|
||||||
(disk_per_cpu * i) as u32,
|
for i in 1..offer.vcpus + 1 {
|
||||||
false,
|
let price_per_month = calculate_nanocredits(
|
||||||
732,
|
i as u32,
|
||||||
node.price,
|
(mem_per_cpu * i) as u32,
|
||||||
) as f64
|
(disk_per_cpu * i) as u32,
|
||||||
/ 1_000_000_000_f64;
|
false,
|
||||||
let price_per_hour = price_per_month / 732_f64;
|
732,
|
||||||
let price_per_month = (price_per_month * 100.0).round() / 100.0;
|
offer.price,
|
||||||
let price_per_hour = (price_per_hour * 1000.0).round() / 1000.0;
|
) as f64
|
||||||
offers.push(NodeOffer {
|
/ 1_000_000_000_f64;
|
||||||
location: node.city.clone() + ", " + &node.region + ", " + &node.country,
|
let price_per_hour = price_per_month / 732_f64;
|
||||||
vcpus: i,
|
let price_per_month = (price_per_month * 100.0).round() / 100.0;
|
||||||
mem: i * mem_per_cpu,
|
let price_per_hour = (price_per_hour * 1000.0).round() / 1000.0;
|
||||||
disk: i * disk_per_cpu,
|
offers.push(NodeOffer {
|
||||||
cost_h: price_per_hour,
|
location: node.city.clone() + ", " + &node.region + ", " + &node.country,
|
||||||
cost_m: price_per_month,
|
vcpus: i,
|
||||||
ipv4: node.public_ipv4,
|
mem: i * mem_per_cpu,
|
||||||
// ipv6: node.public_ipv6,
|
disk: i * disk_per_cpu,
|
||||||
});
|
cost_h: price_per_hour,
|
||||||
|
cost_m: price_per_month,
|
||||||
|
ipv4: node.public_ipv4,
|
||||||
|
// ipv6: node.public_ipv6,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offers.sort_by_key(|n| n.cost_m as u64);
|
offers.sort_by_key(|n| n.cost_m as u64);
|
||||||
|
Loading…
Reference in New Issue
Block a user