added payments for VM creation
This commit is contained in:
parent
1e893b49c0
commit
1a4cec421b
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -215,6 +215,15 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
@ -329,7 +338,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@ -338,6 +346,7 @@ name = "detee-snp-daemon"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58",
|
||||
"ed25519-dalek",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
@ -1103,15 +1112,6 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@ -1712,6 +1712,21 @@ dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.42.0"
|
||||
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ed25519-dalek = { version = "2.1.1", default-features = false, features = ["std", "alloc", "rand_core", "pem"] }
|
||||
ed25519-dalek = { version = "2.1.1", features = [ "rand_core" ] }
|
||||
rand_core = { version = "0.6.4", features = ["alloc", "getrandom", "std"] }
|
||||
anyhow = "1.0.94"
|
||||
env_logger = "0.11.6"
|
||||
@ -21,6 +21,7 @@ tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1.17"
|
||||
tonic = "0.12"
|
||||
serde_json = "1.0.135"
|
||||
bs58 = "0.5.1"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12"
|
||||
|
@ -109,4 +109,4 @@ qemu-system-x86_64 $qemu_device_params \
|
||||
-object memory-backend-memfd,id=ram1,size=$MEMORY,share=true,prealloc=false \
|
||||
-object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,kernel-hashes=on \
|
||||
-kernel $KERNEL -append "$PARAMS" -initrd $INITRD \
|
||||
-nographic -monitor pty -serial mon:stdio -monitor unix:monitor,server,nowait
|
||||
-nographic
|
||||
|
16
snp.proto
16
snp.proto
@ -23,6 +23,10 @@ message Contract {
|
||||
string dtrfs_sha = 12;
|
||||
string created_at = 13;
|
||||
string updated_at = 14;
|
||||
// total nanotoken cost per minute (for all units)
|
||||
uint64 nano_per_minute = 15;
|
||||
uint64 locked_nano = 16;
|
||||
string collected_at = 17;
|
||||
}
|
||||
|
||||
message MeasurementArgs {
|
||||
@ -47,9 +51,11 @@ message RegisterNodeReq {
|
||||
string node_pubkey = 1;
|
||||
string owner_pubkey = 2;
|
||||
string main_ip = 3;
|
||||
string country = 7;
|
||||
string region = 8;
|
||||
string city = 9;
|
||||
string country = 4;
|
||||
string region = 5;
|
||||
string city = 6;
|
||||
// nanotokens per unit per minute
|
||||
uint64 price = 7;
|
||||
}
|
||||
|
||||
message NodeResources {
|
||||
@ -78,6 +84,8 @@ message NewVmReq {
|
||||
string kernel_sha = 12;
|
||||
string dtrfs_url = 13;
|
||||
string dtrfs_sha = 14;
|
||||
uint64 price_per_unit = 15;
|
||||
uint64 locked_nano = 16;
|
||||
}
|
||||
|
||||
message NewVmResp {
|
||||
@ -157,6 +165,8 @@ message NodeListResp {
|
||||
string ip = 5; // required for latency test
|
||||
uint32 server_rating = 6;
|
||||
uint32 provider_rating = 7;
|
||||
// nanotokens per unit per minute
|
||||
uint64 price = 8;
|
||||
}
|
||||
|
||||
service BrainCli {
|
||||
|
@ -53,6 +53,8 @@ pub struct Config {
|
||||
#[serde(with = "range_format")]
|
||||
pub public_port_range: Range<u16>,
|
||||
pub max_ports_per_vm: u16,
|
||||
// price per unit per minute
|
||||
pub price: u64,
|
||||
}
|
||||
|
||||
mod range_format {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use ed25519_dalek::SigningKey;
|
||||
use lazy_static::lazy_static;
|
||||
use log::{info, warn};
|
||||
use std::{fs::File, io::Write};
|
||||
@ -23,39 +24,33 @@ lazy_static! {
|
||||
}
|
||||
|
||||
fn create_secret_key() -> Result<ed25519_dalek::SigningKey> {
|
||||
use ed25519_dalek::pkcs8::{spki::der::pem::LineEnding, EncodePrivateKey};
|
||||
let key_path = SECRET_KEY_PATH;
|
||||
info!("Creating new secret key at {}", key_path);
|
||||
let sk = ed25519_dalek::SigningKey::generate(&mut rand_core::OsRng);
|
||||
let sk_pem = sk.to_pkcs8_pem(LineEnding::default()).unwrap();
|
||||
let private_key_string = bs58::encode(sk.to_bytes()).into_string();
|
||||
let mut file = File::create(key_path)?;
|
||||
file.write_all(sk_pem.as_bytes())?;
|
||||
file.write_all(private_key_string.as_bytes())?;
|
||||
Ok(sk)
|
||||
}
|
||||
|
||||
fn load_secret_key() -> Result<ed25519_dalek::SigningKey> {
|
||||
use ed25519_dalek::pkcs8::DecodePrivateKey;
|
||||
let secret_key_pem = match std::fs::read_to_string(SECRET_KEY_PATH) {
|
||||
let secret_key_string = match std::fs::read_to_string(SECRET_KEY_PATH) {
|
||||
Ok(secret_key_pem) => secret_key_pem,
|
||||
Err(e) => {
|
||||
warn!("Could not load secret key due to error: {e:?}");
|
||||
return Ok(create_secret_key()?);
|
||||
}
|
||||
};
|
||||
Ok(ed25519_dalek::SigningKey::from_pkcs8_pem(&secret_key_pem)?)
|
||||
Ok(SigningKey::from_bytes(
|
||||
&bs58::decode(secret_key_string)
|
||||
.into_vec()?
|
||||
.try_into()
|
||||
.map_err(|_| bs58::decode::Error::BufferTooSmall)?,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn get_public_key() -> String {
|
||||
use ed25519_dalek::pkcs8::{spki::der::pem::LineEnding, EncodePublicKey};
|
||||
let pubkey = load_secret_key()
|
||||
.unwrap()
|
||||
.verifying_key()
|
||||
.to_public_key_pem(LineEnding::default())
|
||||
.unwrap()
|
||||
.lines()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.to_string();
|
||||
let pubkey = bs58::encode(load_secret_key().unwrap().verifying_key().to_bytes()).into_string();
|
||||
log::info!("Loaded the following public key: {pubkey}");
|
||||
pubkey
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ impl From<snp_proto::NodeResources> for snp_proto::DaemonMessage {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn register_node(brain_url: String) -> Result<Vec<Contract>> {
|
||||
let mut client = BrainDaemonClient::connect(brain_url).await?;
|
||||
pub async fn register_node(config: &crate::config::Config) -> Result<Vec<Contract>> {
|
||||
let mut client = BrainDaemonClient::connect(config.brain_url.clone()).await?;
|
||||
debug!("Starting node registration...");
|
||||
let ip_info = IP_INFO.clone();
|
||||
let req = RegisterNodeReq {
|
||||
@ -45,6 +45,7 @@ pub async fn register_node(brain_url: String) -> Result<Vec<Contract>> {
|
||||
country: ip_info.country,
|
||||
region: ip_info.region,
|
||||
city: ip_info.city,
|
||||
price: config.price,
|
||||
};
|
||||
let mut contracts = Vec::new();
|
||||
let mut grpc_stream = client.register_node(req).await?.into_inner();
|
||||
|
@ -243,7 +243,7 @@ async fn main() {
|
||||
let brain_url = vm_handler.config.brain_url.clone();
|
||||
|
||||
info!("Registering with the brain and getting back VM Contracts (if they exist).");
|
||||
match grpc::register_node(brain_url.clone()).await {
|
||||
match grpc::register_node(&vm_handler.config).await {
|
||||
Ok(contracts) => vm_handler.clear_deleted_contracts(contracts),
|
||||
Err(e) => log::error!("Could not get contracts from brain: {e:?}"),
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ impl Resources {
|
||||
}
|
||||
volumes.sort_by_key(|v| v.max_reservation_gb);
|
||||
if let Some(biggest_volume) = volumes.last() {
|
||||
if biggest_volume.max_reservation_gb > required_gb {
|
||||
if biggest_volume.max_reservation_gb >= required_gb {
|
||||
return Some(biggest_volume.path.clone());
|
||||
}
|
||||
}
|
||||
@ -435,6 +435,7 @@ pub struct NewVMRequest {
|
||||
kernel_sha: String,
|
||||
dtrfs_url: String,
|
||||
dtrfs_sha: String,
|
||||
price: u64,
|
||||
}
|
||||
|
||||
impl From<snp_proto::NewVmReq> for NewVMRequest {
|
||||
@ -453,6 +454,7 @@ impl From<snp_proto::NewVmReq> for NewVMRequest {
|
||||
kernel_sha: req.kernel_sha,
|
||||
dtrfs_url: req.dtrfs_url,
|
||||
dtrfs_sha: req.dtrfs_sha,
|
||||
price: req.price_per_unit,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -487,6 +489,7 @@ impl From<snp_proto::UpdateVmReq> for UpdateVMReq {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VMCreationErrors {
|
||||
PriceIsTooLow,
|
||||
VMAlreadyExists(VM),
|
||||
NATandIPv4Conflict,
|
||||
TooManyCores,
|
||||
@ -508,6 +511,9 @@ impl VM {
|
||||
config: &Config,
|
||||
res: &mut Resources,
|
||||
) -> Result<Self, VMCreationErrors> {
|
||||
if req.price < config.price {
|
||||
return Err(VMCreationErrors::PriceIsTooLow);
|
||||
}
|
||||
if res.existing_vms.contains(&req.uuid) {
|
||||
let content = std::fs::read_to_string(VM_CONFIG_DIR.to_string() + &req.uuid + ".yaml")
|
||||
.map_err(|e| VMCreationErrors::ServerDiskError(e.to_string()))?;
|
||||
|
Loading…
Reference in New Issue
Block a user