Skip to content

test: add faucet E2E test - #317

Merged
TomasArrachea merged 28 commits into
nextfrom
ricomateo-e2e-test
Oct 20, 2026
Merged

TomasArrachea merged 28 commits into
nextfrom
ricomateo-e2e-test

Conversation

@ricomateo

@ricomateo ricomateo commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Adds an E2E test that tests the faucet along with a local network and a funding service.

Comment thread .github/workflows/test-e2e.yml Fixed
Comment thread .github/workflows/test-e2e.yml Fixed
Comment thread .github/workflows/test-e2e.yml Fixed
@ricomateo
ricomateo changed the base branch from next to ricomateo-fix-ui-bugs September 24, 2026 20:07
@ricomateo ricomateo added the no changelog This PR does not require an entry in the `CHANGELOG.md` label Sep 24, 2026
const DEFAULT_FAUCET_URL: &str = "https://faucet-api.testnet.miden.io";
const REQUEST_TIMEOUT_MS: u64 = 30_000;
const MAX_SYNC_RETRIES: u32 = 3;
const MAX_SYNC_RETRIES: u32 = 10;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I increased this because 3 attempts was not enough when running the E2E test in the CI

@ricomateo ricomateo changed the title e2e test test: add faucet E2E test Sep 24, 2026
@ricomateo
ricomateo marked this pull request as ready for review September 24, 2026 20:48
Base automatically changed from ricomateo-fix-ui-bugs to next September 24, 2026 21:19
Comment thread scripts/e2e/request-tokens.sh Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we implement this test in Rust instead? Also, I think the other scripts used for setup could just be Rust code as well. For the node, we might look at how the integration tests in the client spin it up, though using docker compose for it could be fine.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think keeping the script to spin the node is fine, the client needs to compile it to be able to pin a specific commit but that is not useful here.

Migrating the test itself to Rust would allow us to remove the install-miden-client.sh script.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I migrated the test to Rust here 8c6c8b1

Comment thread .github/workflows/test-e2e.yml Fixed
Comment thread .github/workflows/test-e2e.yml Fixed
Comment thread .github/workflows/test-e2e.yml Outdated
# is 0.17.0-rc.3. The release run for that tag failed before it built anything, so no images
# were published for it and the newest ones are 0.17.0-rc.2. Remove this once the images are
# published.
NODE_VERSION: 0.17.0-rc.2

@ricomateo ricomateo Sep 25, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The node docker images for 0.17.0-rc.3 haven't been published, so I pinned to the version to the previous one as a temporary fix.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The node rc.4 has been released and it's docker images should also be available.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I unpinned the node version in the CI test here 70c7f6a

@TomasArrachea TomasArrachea left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Left some suggestions for simplifying the code in the test.

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +92 to +101
ClientBuilder::new()
.rpc(Arc::new(VerifyingRpcClient::new(GrpcClient::new(
&endpoint,
REQUEST_TIMEOUT_MS,
))))
.store(Arc::new(store))
.authenticator(Arc::new(keystore))
.build()
.await
.expect("the client should connect to the node")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should we able to use the convenience constructors:

Suggested change
ClientBuilder::new()
.rpc(Arc::new(VerifyingRpcClient::new(GrpcClient::new(
&endpoint,
REQUEST_TIMEOUT_MS,
))))
.store(Arc::new(store))
.authenticator(Arc::new(keystore))
.build()
.await
.expect("the client should connect to the node")
ClientBuilder::<FilesystemKeyStore>::new()
.grpc_client(...)
.filesystem_keystore(...)?
.sqlite_store(...)
.build()
.await
.expect("the client should connect to the node");

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +80 to +83
let work_dir = std::path::Path::new(WORK_DIR);
// A fresh store every run, so a note or account from an earlier run cannot satisfy the test.
let _ = std::fs::remove_dir_all(work_dir);
std::fs::create_dir_all(work_dir.join("keys")).expect("the work directory should be created");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use a temp_dir here. For example for the keystore: temp_dir().join(format!("keystore-{}", Uuid::new_v4()));. Same for the store.

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +106 to +117
let key = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng());
let auth = AuthSingleSig::new(Approver::new(
key.public_key().to_commitment(),
AuthSchemeId::Falcon512Poseidon2,
));

let account = AccountBuilder::new(rand::random())
.account_type(AccountType::Public)
.with_component(auth)
.with_component(BasicWallet)
.build_with_schema_commitment()
.expect("the account should build");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simplify this by using AuthSingleSig::from_public_key() or replace the builder with create_basic_wallet().

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +160 to +175
for attempt in 1..=NOTE_ATTEMPTS {
client.sync_state().await.expect("the client should sync");

let consumable = client
.get_consumable_notes(Some(account_id))
.await
.expect("the consumable notes should be readable");

let found = consumable.into_iter().find(|(record, _)| record.id() == Some(note_id));
if let Some((record, _)) = found {
return record.try_into().expect("a committed note record holds its note");
}

println!("Note not committed yet, attempt {attempt}/{NOTE_ATTEMPTS}");
tokio::time::sleep(NOTE_DELAY).await;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure but we might reuse the wait_for_consumable_notes() method if we use the miden_client::testing::TestClient.

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +182 to +190
let request = TransactionRequestBuilder::new()
.input_notes(vec![(note, None)])
.build()
.expect("the consume request should build");

client
.submit_new_transaction(account_id, request)
.await
.expect("the node should accept the consume transaction");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the TestClient we can use TestClient::consume_notes for this, followed by wait_for_tx.

Comment thread bin/faucet-client/tests/e2e.rs Outdated
Comment on lines +194 to +200
fn fungible_balance(account: &Account) -> u64 {
account
.vault()
.assets()
.filter_map(|asset| asset.as_fungible().map(|asset| asset.amount().as_u64()))
.sum()
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the client.account_reader(account_id).get_balance(faucet_id) for this.

@ricomateo

Copy link
Copy Markdown
Contributor Author

@TomasArrachea thanks! addressed the comments here f3f9b32

Comment thread bin/faucet-client/tests/e2e.rs Outdated
#[ignore = "needs a node, funding service and faucet, run it with `make test-e2e`"]
async fn request_tokens_and_consume_the_note() {
let faucet_url = env_or("FAUCET_URL", DEFAULT_FAUCET_URL);
let node_url = env_or("NODE_URL", DEFAULT_NODE_URL);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we can use miden_client::rpc::Endpoint::localhost() for the node default

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done here d44a6e4

tokio = { features = ["macros", "net", "rt-multi-thread", "time"], workspace = true }
axum = { features = ["tokio"], version = "0.8" }
miden-client = { features = ["testing"], workspace = true }
miden-client-sqlite-store = { workspace = true }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this dep is unused.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this is for creating the client in the test itself

use miden_client_sqlite_store::ClientBuilderSqliteExt;

Comment thread scripts/e2e/faucet.sh Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove this script as well and start the faucet process in the Rust test itself? For the network script it might be okay to use the script for the docker containers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the script and changed the Rust test to start the faucet here 8f4a492

@TomasArrachea
TomasArrachea merged commit d2d0c12 into next Oct 20, 2026
19 checks passed
@TomasArrachea
TomasArrachea deleted the ricomateo-e2e-test branch October 20, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no changelog This PR does not require an entry in the `CHANGELOG.md`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants