Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev-faucet #2061

Merged
merged 43 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2da2342
WIP dev-faucet
cbeck88 May 26, 2022
960b45b
Update mobilecoind-dev-faucet/README.md
cbeck88 May 27, 2022
3d3252c
fixup previous
cbeck88 May 27, 2022
82c9708
fixups
cbeck88 May 27, 2022
651e032
fix clippy
cbeck88 May 27, 2022
fdbfaf4
make the faucet have a background thread that splits tx outs (#2063)
cbeck88 May 31, 2022
01b8080
fix missing async
cbeck88 May 31, 2022
20e4c01
fix after rebase
cbeck88 May 31, 2022
e3a20b0
eran comments
cbeck88 May 31, 2022
10e5003
fix enclave build
cbeck88 May 31, 2022
0715cdf
fix an eran comment about fees
cbeck88 Jun 1, 2022
57c1d2c
dont implement rocket responder, feedback from core-team discussion
cbeck88 Jun 1, 2022
d66d3de
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
ad75beb
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
1a64aae
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
02915f2
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
bfcd0e2
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
c947fb0
Update mobilecoind-dev-faucet/README.md
cbeck88 Jun 1, 2022
64d2125
review comments
cbeck88 Jun 1, 2022
8fd346d
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 1, 2022
4e7d312
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 1, 2022
0edefb8
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 1, 2022
413efc6
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 1, 2022
6ed4e7b
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 2, 2022
c3aa673
remoun review comments (grpcio config)
cbeck88 Jun 2, 2022
3a90a48
move more code into the library for testability
cbeck88 Jun 2, 2022
ed1e716
move worker thread functionality to its own function
cbeck88 Jun 2, 2022
449675f
Update mobilecoind-json/Cargo.toml
cbeck88 Jun 2, 2022
2f1373d
fix code comments
cbeck88 Jun 2, 2022
95c2aaf
add a code comment
cbeck88 Jun 2, 2022
5920a7e
Update mobilecoind-dev-faucet/src/bin/main.rs
cbeck88 Jun 7, 2022
b4c197c
Update mobilecoind-dev-faucet/src/data_types.rs
cbeck88 Jun 7, 2022
bd8809f
Update mobilecoind-dev-faucet/src/lib.rs
cbeck88 Jun 7, 2022
36545a1
Update util/serial/src/lib.rs
cbeck88 Jun 7, 2022
4ac4f4a
Update mobilecoind-dev-faucet/src/worker.rs
cbeck88 Jun 7, 2022
f8d486a
review comments
cbeck88 Jun 8, 2022
f8f0da1
make the faucet retry during initialization
cbeck88 Jun 8, 2022
0bfb9bd
clippy
cbeck88 Jun 8, 2022
da58190
add jsonu64 tests
cbeck88 Jun 8, 2022
6ce26f9
eran comments about Option<JsonU64> vs. #[serde(default)]
cbeck88 Jun 9, 2022
cfdd9c5
Update mobilecoind-dev-faucet/src/lib.rs
cbeck88 Jun 9, 2022
b636906
remove unused import
cbeck88 Jun 9, 2022
af2f966
fix build
cbeck88 Jun 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 26 additions & 58 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ members = [
"mint-auditor",
"mint-auditor/api",
"mobilecoind",
"mobilecoind-dev-faucet",
"mobilecoind-json",
"mobilecoind/api",
"peers",
Expand Down
29 changes: 29 additions & 0 deletions mobilecoind-dev-faucet/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "mc-mobilecoind-dev-faucet"
version = "1.3.0-pre0"
authors = ["MobileCoin"]
edition = "2021"
readme = "README.md"

[[bin]]
name = "mobilecoind-dev-faucet"
path = "src/bin/main.rs"

[dependencies]
mc-account-keys = { path = "../account-keys" }
mc-api = { path = "../api" }
mc-common = { path = "../common", features = ["loggers"] }
mc-mobilecoind-api = { path = "../mobilecoind/api" }
mc-transaction-core = { path = "../transaction/core" }
mc-util-grpc = { path = "../util/grpc" }
mc-util-keyfile = { path = "../util/keyfile" }
mc-util-serial = { path = "../util/serial", features = ["std"] }

clap = { version = "3.1", features = ["derive", "env"] }
grpcio = "0.10.2"
hex = "0.4"
rocket = { version = "0.5.0-rc.2", features = ["json"] }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
tokio = "1"
81 changes: 81 additions & 0 deletions mobilecoind-dev-faucet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
## mobilecoind-dev-faucet

This is a standalone http server which provides faucet functionality.
* Backed by [mobilecoind](../mobilecoind) -- similar to [mobilecoind-json](../mobilecoind-json), it relays requests to a separate mobilecoind instance, and is itself stateless
* No captcha or rate limiting. This is appropriate for developers running automated tests in a dev cluster.
* Any token id can be requested for testing
* TODO: HTTP Authorization headers may be added in the future

### Routes

You may POST to `/`, attaching a json object as the HTTP body:

```
{
b58_address: <string>,
token_id: <optional string>
}
```

Any tokenid can be requested and the faucet will attempt to send a nominal amount of
that token to the address specified, or return errors if it cannot. The nominal amount is
by default twenty times the minimum fee for that token. The response will contain a
JSON object, `success` will be `true` if it managed to submit a payment, and there will
be mobilecoind "Receiver Tx receipt" for the submitted transaction. If `success` is `false`
then `err_str` will describe the problem.

GET requests to `/status`, will respond with a json object with the
following information:

```
{
// The balances of the faucet
balances: { <token_id (string)>:<u64 balance (string)> }
// The amounts the faucet pays per token id
faucet_amounts: { <token_id (string)>:<u64 balance (string)> }
// The current number of "queued" UTXOs. Each can be used to fill a concurrent request.
// If a queue is empty then it may take a few seconds for the faucet to refill the queue.
queue_depths: { <token_id (string)>:<u64 length (string)> }
// This address can be paid to replenish the faucet
b58_address: <string>,
}
```

### Launching

The faucet should be started using a keyfile, which is a json formatted file containing a
mnemonic string or a root entropy for a MobileCoin account.

Required options are:

- `--keyfile` - path to the keyfile with the account mnemonic or entropy. This account holds the faucet funds.

Other options are:
- `--amount-factor` - An integer `X`. The amount we send when people hit the faucet is `minimum_fee * X`. Default is `X = 20`.
- `--listen-host` - hostname for webserver, default `127.0.0.1`
- `--listen-port` - port for webserver, default `9090`
- `--mobilecoind-uri` - URI for connecting to mobilecoind gRPC, default `insecure-mobilecoind://127.0.0.1:4444/`
- `--target-queue-depth` - The number of pre-split transactions the faucet attempts to maintain in its queue. Default is 20.
- `--worker-poll-period-ms` - A lower bound on how often the worker thread wakes up to check in with `mobilecoind`. Default is `100` milliseconds.

### Usage with cURL

Here is some example usage:

Requesting payment:

```
$ curl -s localhost:9090/ -d '{"b58_address": "c7f04fcd40d093ca6578b13d790df0790c96e94a77815e5052993af1b9d12923"}' -X POST -H 'Content-type: application/json'
{"success":true,"receiver_tx_receipt_list":[{"recipient":{"view_public_key":"86280244d51afed4217ee3dc6288650c27cacc6e4bfb558159f0f8caa38ae542","spend_public_key":"803958b71de5fa7a58d257a0411506e59f77eaff33ee7b7905ac4f9ef68e3c2a","fog_report_url":"","fog_authority_sig":"","fog_report_id":""},"tx_public_key":"880d56bc36411507131098dd404878fb083b6dd5b805c37f736dcfa94d31027d","tx_out_hash":"0fbe90326c255e08b3ee6cbdf626d244ac29bbdab8810163d09513fa1919664f","tombstone":56,"confirmation_number":"027c506b81ad5bd8142382c75f6148f6e5627ad45d2a09110ee9e4ff5a789398"}]}```

```
$ curl -s localhost:9090/ -d '{"b58_address": "c7f04fcd40d093ca6578b13d790df0790c96e94a77815e5052993af1b9d12923", "token_id": "1"}' -X POST -H 'Content-type: application/json'
{"success":false,"err_str":"faucet is depleted"}
```

Getting status:

```
$ curl -s localhost:9090/status
{"b58_address":"5KBMnd8cs5zPsytGgZrjmQ8z9VJYThuh1B39pKzDERTfzm3sVGQxnZPC8JEWP69togpSPRz3e6pBsLzwnMjrXTbDqoRTQ8VF98sQu7LqjL5","faucet_payout_amounts":{"2":"20480","1":"20480","0":"8000000000"},"balances":{"2":"0","1":"0","0":"12499999997600000000"},"queue_depths":{"1":"0","0":"26","2":"0"}}
```
73 changes: 73 additions & 0 deletions mobilecoind-dev-faucet/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2018-2022 The MobileCoin Foundation

#![deny(missing_docs)]

//! HTTP faucet service backed by mobilecoind

#![feature(proc_macro_hygiene, decl_macro)]
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved

use clap::Parser;
use mc_common::logger::{create_app_logger, log, o};
use mc_mobilecoind_dev_faucet::{data_types::*, Config, State};
use rocket::{get, post, routes, serde::json::Json};

/// Request payment from the faucet, and map the rust result onto json for
/// rocket appropriately
#[post("/", format = "json", data = "<req>")]
async fn post(
state: &rocket::State<State>,
req: Json<JsonFaucetRequest>,
) -> Json<JsonSubmitTxResponse> {
Json(match state.handle_post(&req).await {
Ok(resp) => resp.into(),
Err(err_str) => JsonSubmitTxResponse {
success: false,
err_str: Some(err_str),
..Default::default()
},
})
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
}

/// Request status of the faucet, and map the rust result onto json for rocket
/// apporpriately
#[get("/status")]
async fn status(state: &rocket::State<State>) -> Json<JsonFaucetStatus> {
Json(match state.handle_status().await {
Ok(resp) => resp,
Err(err_str) => JsonFaucetStatus {
success: false,
err_str: Some(err_str),
..Default::default()
},
})
}

#[rocket::main]
async fn main() -> Result<(), rocket::Error> {
mc_common::setup_panic_handler();
let _sentry_guard = mc_common::sentry::init();

let config = Config::parse();

let (logger, _global_logger_guard) = create_app_logger(o!());
log::info!(
logger,
"Starting mobilecoind-dev-faucet HTTP on {}:{}, connecting to {}",
config.listen_host,
config.listen_port,
config.mobilecoind_uri,
);

let figment = rocket::Config::figment()
.merge(("port", config.listen_port))
.merge(("address", config.listen_host.clone()));

let state = State::new(&config, &logger).expect("Could not initialize");

let _rocket = rocket::custom(figment)
.mount("/", routes![post, status])
.manage(state)
.launch()
.await?;
remoun marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}
Loading