added skeleton for Solana integration
`
This commit is contained in:
parent
3b5b55e44e
commit
118fd077b4
2533
rewrite/Cargo.lock
generated
2533
rewrite/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ prost = "0.13.2"
|
||||
prost-types = "0.13.2"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.210", features = ["derive"] }
|
||||
solana-client = "2.0.11"
|
||||
solana-sdk = "2.0.10"
|
||||
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread", "fs"] }
|
||||
tokio-stream = { version = "0.1.16", features = ["sync"] }
|
||||
|
@ -14,13 +14,14 @@ message NodeUpdate {
|
||||
bool public = 8;
|
||||
}
|
||||
|
||||
message Keypair {
|
||||
message Keys {
|
||||
string keypair = 1;
|
||||
string token_address = 2;
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
service Update {
|
||||
rpc GetKeypair (Empty) returns (Keypair);
|
||||
rpc GetKeys (Empty) returns (Keys);
|
||||
rpc GetUpdates (stream NodeUpdate) returns (stream NodeUpdate);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#![allow(dead_code)]
|
||||
use dashmap::DashMap;
|
||||
use dashmap::DashSet;
|
||||
use solana_sdk::signature::keypair::Keypair;
|
||||
use std::time::Duration;
|
||||
use std::time::SystemTime;
|
||||
use crate::solana::Client as SolClient;
|
||||
|
||||
type IP = String;
|
||||
pub const LOCALHOST: &str = "localhost";
|
||||
@ -38,7 +38,7 @@ impl NodeInfo {
|
||||
/// This means the first node of the network creates the key
|
||||
/// Second node will grab the key from the first node
|
||||
pub struct Store {
|
||||
key: Keypair,
|
||||
sol_client: SolClient,
|
||||
nodes: DashMap<IP, NodeInfo>,
|
||||
conns: DashSet<IP>,
|
||||
// TODO: write persistence
|
||||
@ -46,9 +46,9 @@ pub struct Store {
|
||||
}
|
||||
|
||||
impl Store {
|
||||
pub fn init(key: Keypair) -> Self {
|
||||
pub fn init(sol_client: SolClient) -> Self {
|
||||
let store = Self {
|
||||
key,
|
||||
sol_client,
|
||||
nodes: DashMap::new(),
|
||||
conns: DashSet::new(),
|
||||
};
|
||||
@ -67,8 +67,12 @@ impl Store {
|
||||
store
|
||||
}
|
||||
|
||||
pub fn get_token_address(&self) -> String {
|
||||
self.sol_client.token_address()
|
||||
}
|
||||
|
||||
pub fn get_keypair_base58(&self) -> String {
|
||||
self.key.to_base58_string()
|
||||
self.sol_client.get_keypair_base58()
|
||||
}
|
||||
|
||||
pub fn add_conn(&self, ip: &str) {
|
||||
|
@ -1,15 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
use super::challenge::NodeUpdate;
|
||||
use crate::datastore::Store;
|
||||
use crate::datastore::LOCALHOST;
|
||||
use crate::grpc::challenge::update_client::UpdateClient;
|
||||
use crate::grpc::challenge::Empty;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::keypair::Keypair;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast::Sender;
|
||||
use tokio::time::{sleep, Duration};
|
||||
use tokio_stream::wrappers::BroadcastStream;
|
||||
use tokio_stream::StreamExt;
|
||||
use crate::datastore::LOCALHOST;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConnManager {
|
||||
@ -55,7 +57,9 @@ impl ConnManager {
|
||||
let response = client.get_updates(rx_stream).await?;
|
||||
let mut resp_stream = response.into_inner();
|
||||
|
||||
let _ = self.tx.send((LOCALHOST.to_string(), self.ds.get_localhost()).into());
|
||||
let _ = self
|
||||
.tx
|
||||
.send((LOCALHOST.to_string(), self.ds.get_localhost()).into());
|
||||
|
||||
while let Some(mut update) = resp_stream.message().await? {
|
||||
// "localhost" IPs need to be changed to the real IP of the counterpart
|
||||
@ -78,13 +82,16 @@ impl ConnManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn key_grabber(node_ip: String) -> Result<Keypair, Box<dyn std::error::Error>> {
|
||||
pub async fn key_grabber(node_ip: String) -> Result<(Keypair, Pubkey), Box<dyn std::error::Error>> {
|
||||
let mut client = UpdateClient::connect(format!("http://{node_ip}:31373")).await?;
|
||||
let response = client.get_keypair(tonic::Request::new(Empty {})).await?;
|
||||
let response = &response.into_inner().keypair;
|
||||
let keypair = match std::panic::catch_unwind(|| Keypair::from_base58_string(&response)) {
|
||||
let response = client.get_keys(tonic::Request::new(Empty {})).await?;
|
||||
let response = &response.into_inner();
|
||||
let keypair = response.keypair.clone();
|
||||
let keypair = match std::panic::catch_unwind(|| Keypair::from_base58_string(&keypair)) {
|
||||
Ok(k) => k,
|
||||
Err(_) => return Err("Could not parse key".into()),
|
||||
Err(_) => return Err("Could not parse keypair.".into()),
|
||||
};
|
||||
Ok(keypair)
|
||||
let token_address = Pubkey::from_str(&response.token_address)
|
||||
.map_err(|_| "Could not parse wallet address.".to_string())?;
|
||||
Ok((keypair, token_address))
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::challenge::update_server::UpdateServer;
|
||||
use super::challenge::{Empty, Keypair, NodeUpdate};
|
||||
use super::challenge::{Empty, Keys, NodeUpdate};
|
||||
use crate::datastore::Store;
|
||||
use crate::grpc::challenge::update_server::Update;
|
||||
use std::pin::Pin;
|
||||
@ -90,11 +90,12 @@ impl Update for MyServer {
|
||||
Ok(Response::new(Box::pin(stream) as Self::GetUpdatesStream))
|
||||
}
|
||||
|
||||
async fn get_keypair(&self, request: Request<Empty>) -> Result<Response<Keypair>, Status> {
|
||||
async fn get_keys(&self, request: Request<Empty>) -> Result<Response<Keys>, Status> {
|
||||
println!("Got a request from {:?}", request.remote_addr());
|
||||
|
||||
let reply = Keypair {
|
||||
let reply = Keys {
|
||||
keypair: self.ds.get_keypair_base58(),
|
||||
token_address: self.ds.get_token_address(),
|
||||
};
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ pub struct NodesResp {
|
||||
pub mint_requests: u64,
|
||||
pub mints: u64,
|
||||
pub ratls_attacks: u64,
|
||||
pub ratls_connections: u64,
|
||||
pub total_ratls_conns: u64,
|
||||
pub public: bool,
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ impl From<(String, datastore::NodeInfo)> for NodesResp {
|
||||
joined_at,
|
||||
last_keepalive,
|
||||
mints: node_info.mints,
|
||||
ratls_connections: node_info.ratls_conns,
|
||||
total_ratls_conns: node_info.ratls_conns,
|
||||
ratls_attacks: node_info.ratls_attacks,
|
||||
public: node_info.public,
|
||||
mint_requests: node_info.mint_requests,
|
||||
|
@ -1,10 +1,10 @@
|
||||
mod datastore;
|
||||
mod grpc;
|
||||
mod http_server;
|
||||
mod solana;
|
||||
use crate::datastore::LOCALHOST;
|
||||
use crate::grpc::challenge::NodeUpdate;
|
||||
use datastore::Store;
|
||||
use solana_sdk::signature::keypair::Keypair;
|
||||
use solana_sdk::signer::Signer;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
@ -12,8 +12,8 @@ use std::sync::Arc;
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::sync::broadcast::Sender;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
use tokio::task::JoinSet;
|
||||
use crate::solana::Client as SolClient;
|
||||
|
||||
const INIT_NODES: &str = "detee_challenge_nodes";
|
||||
|
||||
@ -25,24 +25,25 @@ pub async fn localhost_cron(ds: Arc<Store>, tx: Sender<NodeUpdate>) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_keypair() -> Keypair {
|
||||
async fn get_sol_client() -> SolClient {
|
||||
let input = match File::open(INIT_NODES) {
|
||||
Ok(i) => i,
|
||||
Err(_) => {
|
||||
println!("Could not find remote nodes in the file {INIT_NODES}");
|
||||
println!("Starting a new network with a new key...");
|
||||
return Keypair::new();
|
||||
return SolClient::new().await;
|
||||
}
|
||||
};
|
||||
let buffered = BufReader::new(input);
|
||||
for line in buffered.lines() {
|
||||
match grpc::client::key_grabber(line.unwrap()).await {
|
||||
Ok(keypair) => {
|
||||
Ok(bundle) => {
|
||||
println!(
|
||||
"Got keypair from the network. Joining the network using wallet {}.",
|
||||
keypair.pubkey()
|
||||
bundle.0.pubkey()
|
||||
);
|
||||
return keypair;
|
||||
println!("The address of the Token is {}.", bundle.1.to_string());
|
||||
return SolClient::from(bundle.0, bundle.1);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Could not get keypair: {e:?}");
|
||||
@ -54,8 +55,8 @@ async fn get_keypair() -> Keypair {
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let keypair = get_keypair().await;
|
||||
let ds = Arc::new(Store::init(keypair));
|
||||
let sol_client = get_sol_client().await;
|
||||
let ds = Arc::new(Store::init(sol_client));
|
||||
|
||||
let (tx, mut _rx) = broadcast::channel(500);
|
||||
|
||||
|
63
rewrite/src/solana.rs
Normal file
63
rewrite/src/solana.rs
Normal file
@ -0,0 +1,63 @@
|
||||
#![allow(dead_code)]
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::keypair::Keypair;
|
||||
use solana_sdk::signer::Signer;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
const RPC_URL: &str = "https://api.devnet.solana.com";
|
||||
|
||||
pub struct Client {
|
||||
client: RpcClient,
|
||||
keypair: Keypair,
|
||||
token: Pubkey,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn new() -> Self {
|
||||
let client = RpcClient::new(RPC_URL);
|
||||
let keypair = Keypair::new();
|
||||
let token = create_token(&client, &keypair).await;
|
||||
Self {
|
||||
client,
|
||||
keypair,
|
||||
token,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(keypair: Keypair, token: Pubkey) -> Self {
|
||||
Self {
|
||||
client: RpcClient::new(RPC_URL),
|
||||
keypair,
|
||||
token,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wallet_address(&self) -> String {
|
||||
self.keypair.pubkey().to_string()
|
||||
}
|
||||
|
||||
pub fn token_address(&self) -> String {
|
||||
self.token.to_string()
|
||||
}
|
||||
|
||||
pub fn get_keypair_base58(&self) -> String {
|
||||
self.keypair.to_base58_string()
|
||||
}
|
||||
}
|
||||
|
||||
async fn wait_for_sol(client: &RpcClient, pubkey: &Pubkey) {
|
||||
loop {
|
||||
sleep(Duration::from_secs(30)).await;
|
||||
if let Ok(balance) = client.get_balance(pubkey) {
|
||||
if balance > 1_000_000_000 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_token(client: &RpcClient, keypair: &Keypair) -> Pubkey {
|
||||
wait_for_sol(client, &keypair.pubkey()).await;
|
||||
todo!();
|
||||
}
|
Loading…
Reference in New Issue
Block a user