1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use clap::{crate_description, crate_name, App, Arg};
use solana_clap_utils::input_parsers::{lamports_of_sol, value_of};
use solana_faucet::{
    faucet::{run_faucet, Faucet, FAUCET_PORT},
    socketaddr,
};
use solana_sdk::signature::read_keypair_file;
use std::{
    net::{Ipv4Addr, SocketAddr},
    sync::{Arc, Mutex},
    thread,
};

#[tokio::main]
async fn main() {
    let default_keypair = solana_cli_config::Config::default().keypair_path;

    solana_logger::setup_with_default("solana=info");
    solana_metrics::set_panic_hook("faucet");
    let matches = App::new(crate_name!())
        .about(crate_description!())
        .version(solana_version::version!())
        .arg(
            Arg::with_name("keypair")
                .short("k")
                .long("keypair")
                .value_name("PATH")
                .takes_value(true)
                .required(true)
                .default_value(&default_keypair)
                .help("File from which to read the faucet's keypair"),
        )
        .arg(
            Arg::with_name("slice")
                .long("slice")
                .value_name("SECS")
                .takes_value(true)
                .help("Time slice over which to limit requests to faucet"),
        )
        .arg(
            Arg::with_name("per_time_cap")
                .long("per-time-cap")
                .alias("cap")
                .value_name("NUM")
                .takes_value(true)
                .help("Request limit for time slice, in VLX"),
        )
        .arg(
            Arg::with_name("per_request_cap")
                .long("per-request-cap")
                .value_name("NUM")
                .takes_value(true)
                .help("Request limit for a single request, in VLX"),
        )
        .get_matches();

    let faucet_keypair = read_keypair_file(matches.value_of("keypair").unwrap())
        .expect("failed to read client keypair");

    let time_slice = value_of(&matches, "slice");
    let per_time_cap = lamports_of_sol(&matches, "per_time_cap");
    let per_request_cap = lamports_of_sol(&matches, "per_request_cap");

    let faucet_addr = socketaddr!(0, FAUCET_PORT);

    let faucet = Arc::new(Mutex::new(Faucet::new(
        faucet_keypair,
        time_slice,
        per_time_cap,
        per_request_cap,
    )));

    let faucet1 = faucet.clone();
    thread::spawn(move || loop {
        let time = faucet1.lock().unwrap().time_slice;
        thread::sleep(time);
        faucet1.lock().unwrap().clear_request_count();
    });

    run_faucet(faucet, faucet_addr, None).await;
}