Skip to content

Commit

Permalink
Allow many inputs to faucet
Browse files Browse the repository at this point in the history
  • Loading branch information
CapCap authored and aptos-bot committed Apr 1, 2022
1 parent 5645f83 commit 635d27f
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 19 deletions.
13 changes: 9 additions & 4 deletions crates/aptos-faucet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,15 @@ pub async fn delegate_mint_account(
&service,
mint::MintParams {
amount: 100_000_000_000,
auth_key: delegated_account
.authentication_key()
.clone()
.derived_address(),
auth_key: None,
address: Some(
delegated_account
.authentication_key()
.clone()
.derived_address()
.to_hex_literal(),
),
pub_key: None,
return_txns: Some(true),
},
)
Expand Down
75 changes: 72 additions & 3 deletions crates/aptos-faucet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,10 @@ mod tests {
}

#[tokio::test]
async fn test_mint() {
async fn test_mint_auth_key() {
let (accounts, service) = setup(None);
let filter = routes(service);

// auth_key is outside of the loop for minting same account multiple times,
// it should succeed and should not create same account multiple times.
let auth_key = "459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d";
let amount = 13345;
let resp = warp::test::request()
Expand All @@ -347,6 +345,77 @@ mod tests {
assert_eq!(account.balance, amount);
}

#[tokio::test]
async fn test_mint_pub_key() {
let (accounts, service) = setup(None);
let filter = routes(service);

let pub_key = "459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d";
let amount = 13345;
let resp = warp::test::request()
.method("POST")
.path(format!("/mint?pub_key={}&amount={}", pub_key, amount).as_str())
.reply(&filter)
.await;
let values: Vec<HashValue> = serde_json::from_slice(resp.body()).unwrap();
assert_eq!(values.len(), 2);
let reader = accounts.read();
let addr = AccountAddress::try_from(
"9FF98E82355EB13098F3B1157AC018A725C62C0E0820F422000814CDBA407835".to_owned(),
)
.unwrap();
let account = reader.get(&addr).expect("account should be created");
assert_eq!(account.balance, amount);
}

#[tokio::test]
async fn test_mint_address() {
let (accounts, service) = setup(None);
let filter = routes(service);

let address = "459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d";
let amount = 13345;
let resp = warp::test::request()
.method("POST")
.path(format!("/mint?address={}&amount={}", address, amount).as_str())
.reply(&filter)
.await;

let values: Vec<HashValue> = serde_json::from_slice(resp.body()).unwrap();
assert_eq!(values.len(), 2);
let reader = accounts.read();
let addr = AccountAddress::try_from(
"459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d".to_owned(),
)
.unwrap();
let account = reader.get(&addr).expect("account should be created");
assert_eq!(account.balance, amount);
}

#[tokio::test]
async fn test_mint_address_hex() {
let (accounts, service) = setup(None);
let filter = routes(service);

let address = "0x459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d";
let amount = 13345;
let resp = warp::test::request()
.method("POST")
.path(format!("/mint?address={}&amount={}", address, amount).as_str())
.reply(&filter)
.await;

let values: Vec<HashValue> = serde_json::from_slice(resp.body()).unwrap();
assert_eq!(values.len(), 2);
let reader = accounts.read();
let addr = AccountAddress::try_from(
"459c77a38803bd53f3adee52703810e3a74fd7c46952c497e75afb0a7932586d".to_owned(),
)
.unwrap();
let account = reader.get(&addr).expect("account should be created");
assert_eq!(account.balance, amount);
}

#[tokio::test]
async fn test_mint_with_txns_response() {
let (accounts, service) = setup(None);
Expand Down
48 changes: 36 additions & 12 deletions crates/aptos-faucet/src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

use crate::Service;
use anyhow::Result;
use aptos_crypto::hash::HashValue;
use aptos_crypto::{ed25519::Ed25519PublicKey, hash::HashValue};
use aptos_logger::{error, info, warn};
use aptos_sdk::{
transaction_builder::aptos_stdlib,
types::{account_address::AccountAddress, transaction::SignedTransaction},
types::{
account_address::AccountAddress,
transaction::{authenticator::AuthenticationKey, SignedTransaction},
},
};
use reqwest::StatusCode;
use serde::Deserialize;
Expand All @@ -17,8 +20,8 @@ use warp::{Filter, Rejection, Reply};
pub fn mint_routes(
service: Arc<Service>,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
// POST /?amount=25&pub_key=xxx
// POST /mint?amount=25&pub_key=xxx
// POST /?amount=25&address=xxx
// POST /mint?amount=25&address=xxx
warp::path::end()
.or(warp::path::path("mint"))
.and(warp::post())
Expand Down Expand Up @@ -62,7 +65,9 @@ impl std::fmt::Display for Response {
#[derive(Deserialize, Debug)]
pub struct MintParams {
pub amount: u64,
pub auth_key: AccountAddress,
pub auth_key: Option<AccountAddress>,
pub address: Option<String>,
pub pub_key: Option<Ed25519PublicKey>,
pub return_txns: Option<bool>,
}

Expand All @@ -73,16 +78,35 @@ impl std::fmt::Display for MintParams {
}

impl MintParams {
fn receiver(&self) -> AccountAddress {
self.auth_key
fn receiver(&self) -> Option<AccountAddress> {
if let Some(auth_key) = self.auth_key {
return Some(auth_key);
}
if let Some(address) = self.address.as_ref() {
return match AccountAddress::from_hex_literal(address) {
Ok(address) => Some(address),
Err(_) => match AccountAddress::from_hex(address) {
Ok(address) => Some(address),
Err(_) => None,
},
};
}
if let Some(pub_key) = self.pub_key.as_ref() {
return Some(AuthenticationKey::ed25519(pub_key).derived_address());
}
None
}
}

pub async fn process(service: &Service, params: MintParams) -> Result<Response> {
let maybe_maximum_amount = service.maximum_amount.unwrap_or(params.amount);
let amount = std::cmp::min(params.amount, maybe_maximum_amount);

let (mut faucet_seq, mut receiver_seq) = sequences(service, params.receiver()).await?;
let receiver_address = params.receiver().ok_or_else(|| {
anyhow::format_err!("You must provide 'address' (preferred), 'pub_key', or 'auth_key'")
})?;

let (mut faucet_seq, mut receiver_seq) = sequences(service, receiver_address).await?;
let our_faucet_seq = {
let mut faucet_account = service.faucet_account.lock().unwrap();

Expand All @@ -105,7 +129,7 @@ pub async fn process(service: &Service, params: MintParams) -> Result<Response>
);

tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
let (lhs, rhs) = sequences(service, params.receiver()).await?;
let (lhs, rhs) = sequences(service, receiver_address).await?;
faucet_seq = lhs;
receiver_seq = rhs;
}
Expand All @@ -115,7 +139,7 @@ pub async fn process(service: &Service, params: MintParams) -> Result<Response>
error!("We are unhealthy, transactions have likely expired.");
let mut faucet_account = service.faucet_account.lock().unwrap();
if faucet_account.sequence_number() >= faucet_seq + 50 {
info!("Reseting the sequence number counter.");
info!("Resetting the sequence number counter.");
*faucet_account.sequence_number_mut() = faucet_seq;
} else {
info!("Someone else reset the sequence number counter ahead of us.");
Expand All @@ -129,7 +153,7 @@ pub async fn process(service: &Service, params: MintParams) -> Result<Response>

if receiver_seq.is_none() {
let builder = service.transaction_factory.payload(
aptos_stdlib::encode_create_account_script_function(params.receiver()),
aptos_stdlib::encode_create_account_script_function(receiver_address),
);

let txn = faucet_account.sign_with_transaction_builder(builder);
Expand All @@ -139,7 +163,7 @@ pub async fn process(service: &Service, params: MintParams) -> Result<Response>
if amount != 0 {
txns.push(
faucet_account.sign_with_transaction_builder(service.transaction_factory.payload(
aptos_stdlib::encode_mint_script_function(params.receiver(), amount),
aptos_stdlib::encode_mint_script_function(receiver_address, amount),
)),
);
}
Expand Down

0 comments on commit 635d27f

Please sign in to comment.