-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commits adds a migration binary to moves clients on a postgresql…
… db to a smart contract db
- Loading branch information
Showing
10 changed files
with
316 additions
and
13 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
//! This binary is run to have access to a postgresql db, takes its client info and writes it into | ||
//! smart contract. This is necessary setup to move existing registered clients from the previous | ||
//! sql db format to a smart contract | ||
#![warn(clippy::all)] | ||
#![allow(clippy::pedantic)] | ||
#![forbid(unsafe_code)] | ||
|
||
use docopt::Docopt; | ||
use log::{error, info}; | ||
use rita_client_registration::register_client_batch_loop::register_client_batch_loop; | ||
use rita_db_migration::start_db_migration; | ||
use serde::Deserialize; | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub struct Args { | ||
pub sql_db_url: String, | ||
pub address: String, | ||
pub web3_url: String, | ||
pub private_key: String, | ||
} | ||
|
||
fn main() { | ||
let args: Args = Docopt::new(get_arg_usage()) | ||
.and_then(|d| d.deserialize()) | ||
.unwrap_or_else(|e| e.exit()); | ||
|
||
let db_url = args.sql_db_url; | ||
let contract_addr = args | ||
.address | ||
.parse() | ||
.expect("Please provide a valid eth contract addr"); | ||
let web3_url = args.web3_url; | ||
let private_key = args | ||
.private_key | ||
.parse() | ||
.expect("Please provide a valid eth private key with funds"); | ||
|
||
let system = actix_async::System::new(); | ||
|
||
// Start registration loop | ||
register_client_batch_loop(web3_url, contract_addr, private_key); | ||
|
||
match start_db_migration(db_url) { | ||
Ok(_) => println!("Successfully migrated all clients!"), | ||
Err(e) => println!("Failed to migrate clients with {}", e), | ||
} | ||
|
||
if let Err(e) = system.run() { | ||
error!("Starting Rita DB migration failed with {}", e); | ||
} | ||
info!("Started Rita DB migration!"); | ||
} | ||
|
||
pub fn get_arg_usage() -> String { | ||
"Usage: rita_db_migration [--db_url=<db_url>] [--address=<address>] [--web3_url=<web3_url>] [--private_key=<private_key>] | ||
Options: | ||
-u, --db_url=<db_url> Postgresql db url | ||
-a, --address=<address> Smart Contract address | ||
-w, --web3_url=<web3_url> Web3 url | ||
-p, --private_key=<private_key> Our Private key | ||
About: | ||
Db migration binary".to_string() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "rita_db_migration" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
r2d2 = "0.8" | ||
diesel = { version = "1.4", features = ["postgres", "r2d2"] } | ||
log = { version = "0.4", features = ["release_max_level_info"] } | ||
dotenv = "0.15" | ||
althea_types = { path = "../althea_types" } | ||
serde = "1.0" | ||
serde_derive = "1.0" | ||
serde_json = "1.0" | ||
rita_client_registration = { path = "../rita_client_registration" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use std::{ | ||
error::Error, | ||
fmt::{Display, Formatter, Result as FmtResult}, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub enum RitaDBMigrationError { | ||
MiscStringError(String), | ||
} | ||
|
||
impl Display for RitaDBMigrationError { | ||
fn fmt(&self, f: &mut Formatter) -> FmtResult { | ||
match self { | ||
RitaDBMigrationError::MiscStringError(a) => write!(f, "{a}",), | ||
} | ||
} | ||
} | ||
|
||
impl Error for RitaDBMigrationError {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#[macro_use] | ||
extern crate log; | ||
#[macro_use] | ||
extern crate diesel; | ||
#[macro_use] | ||
extern crate serde_derive; | ||
|
||
pub mod error; | ||
pub mod models; | ||
pub mod schema; | ||
|
||
use crate::schema::clients::dsl::clients; | ||
use althea_types::Identity; | ||
use diesel::{r2d2::ConnectionManager, PgConnection, RunQueryDsl}; | ||
use error::RitaDBMigrationError; | ||
use models::Client; | ||
use r2d2::PooledConnection; | ||
use rita_client_registration::add_client_to_reg_batch; | ||
|
||
pub fn start_db_migration(db_url: String) -> Result<(), RitaDBMigrationError> { | ||
// Validate that db_url and contract_addr are valid | ||
if !(db_url.contains("postgres://") | ||
|| db_url.contains("postgresql://") | ||
|| db_url.contains("psql://")) | ||
{ | ||
panic!("You must provide a valid postgressql database uri!"); | ||
} | ||
|
||
let db_conn = get_database_connection(db_url)?; | ||
|
||
if let Ok(clients_list) = clients.load::<models::Client>(&db_conn) { | ||
info!( | ||
"Recieved a valid client list with {} entries", | ||
clients_list.len() | ||
); | ||
|
||
add_clients_to_reg_queue(clients_list) | ||
} else { | ||
return Err(RitaDBMigrationError::MiscStringError( | ||
"Unable to get db clients".to_string(), | ||
)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn add_clients_to_reg_queue(client_list: Vec<Client>) { | ||
for c in client_list { | ||
let id = Identity { | ||
mesh_ip: match c.mesh_ip.parse() { | ||
Ok(a) => a, | ||
Err(e) => { | ||
error!("Cannot parse client {:?} mesh ip! with {}", c, e); | ||
continue; | ||
} | ||
}, | ||
eth_address: match c.eth_address.parse() { | ||
Ok(a) => a, | ||
Err(e) => { | ||
error!("Cannot parse client {:?} eth addr! with {}", c, e); | ||
continue; | ||
} | ||
}, | ||
wg_public_key: match c.wg_pubkey.parse() { | ||
Ok(a) => a, | ||
Err(e) => { | ||
error!("Cannot parse client {:?} wg key! with {}", c, e); | ||
continue; | ||
} | ||
}, | ||
nickname: None, | ||
}; | ||
|
||
add_client_to_reg_batch(id); | ||
} | ||
} | ||
|
||
pub fn get_database_connection( | ||
db_url: String, | ||
) -> Result<PooledConnection<ConnectionManager<PgConnection>>, RitaDBMigrationError> { | ||
let manager = ConnectionManager::new(db_url); | ||
let pool = r2d2::Pool::builder() | ||
.max_size(1) | ||
.build(manager) | ||
.expect("Failed to create pool."); | ||
|
||
match pool.try_get() { | ||
Some(connection) => Ok(connection), | ||
None => { | ||
error!("No available db connection!"); | ||
Err(RitaDBMigrationError::MiscStringError( | ||
"No Database connection available!".to_string(), | ||
)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#![allow(clippy::extra_unused_lifetimes)] | ||
use crate::schema::{assigned_ips, clients}; | ||
|
||
#[derive(Queryable, Serialize, Deserialize, Debug, Insertable, Clone, Default)] | ||
#[table_name = "clients"] | ||
pub struct Client { | ||
pub mesh_ip: String, | ||
pub wg_pubkey: String, | ||
pub wg_port: i32, | ||
pub eth_address: String, | ||
pub internal_ip: String, | ||
pub internet_ipv6: String, | ||
pub nickname: String, | ||
pub email: String, | ||
pub phone: String, | ||
pub country: String, | ||
pub email_code: String, | ||
pub verified: bool, | ||
pub email_sent_time: i64, | ||
pub text_sent: i32, | ||
pub last_seen: i64, | ||
pub last_balance_warning_time: i64, | ||
} | ||
|
||
/// This struct holds information about the ipv6 subnets being assigned to clients who connect. | ||
/// The vector available subnets is a stack that has a list of available subnets to use. This stack gets populated whenever | ||
/// a client gets removed from the database. It is stored as a string of indecies, for example, "1,24,36" | ||
/// The iterative index stores the index at which we assign a subnet to a client | ||
/// For example, if our exit subnet is fd00::1000/120 and our client subnets are /124, index 0 represents | ||
/// fd00::1000/124 index 1 represents fd00::1010/124, 2 is fd00::1120/124 etc... | ||
#[derive(Queryable, Serialize, Deserialize, Debug, Insertable, Clone, Default)] | ||
#[table_name = "assigned_ips"] | ||
pub struct AssignedIps { | ||
pub subnet: String, | ||
pub available_subnets: String, | ||
pub iterative_index: i64, | ||
} |
Oops, something went wrong.