Skip to content

Commit bb56c7c

Browse files
committed
enable injecting bootnode urls via env vars when in docker
1 parent 41f8082 commit bb56c7c

File tree

8 files changed

+113
-21
lines changed

8 files changed

+113
-21
lines changed

frontend/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
# REQUIRED ENVIRONMENT VARIABLES:
2828
# MINA_FRONTEND_ENVIRONMENT - Frontend configuration (local|webnode|production|fuzzing|staging)
2929
#
30+
# OPTIONAL ENVIRONMENT VARIABLES:
31+
# MINA_WEBNODE_SEED_URLS - Comma separated list of HTTP(S) urls to fetch bootnodes from
32+
# MINA_WEBNODE_BOOTNODES - Comma separated list of multiaddrs to use as bootnodes
33+
#
3034
# USAGE:
3135
# # Generate .env.docker with current git information
3236
# ./generate-docker-env.sh

frontend/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Frontend Makefile
22

3+
# These are threaded from the outside env into build-webnode
4+
MINA_WEBNODE_SEED_URLS ?=
5+
MINA_WEBNODE_BOOTNODES ?=
6+
37
.PHONY: help
48
help: ## Display this help message
59
@echo "Frontend Makefile - Available targets:"
@@ -38,7 +42,10 @@ build-production: ## Build the frontend with production configuration
3842

3943
.PHONY: build-webnode
4044
build-webnode: ## Build the frontend with webnode configuration
41-
npx ng build --configuration webnode-local
45+
npx ng build \
46+
--define MINA_WEBNODE_SEED_URLS="\"$(MINA_WEBNODE_SEED_URLS)\"" \
47+
--define MINA_WEBNODE_BOOTNODES="\"$(MINA_WEBNODE_BOOTNODES)\"" \
48+
--configuration webnode-local
4249
cp dist/frontend/browser/assets/environments/webnode.js \
4350
dist/frontend/browser/assets/environments/env.js
4451

frontend/angular.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@
6262
},
6363
"scripts": [
6464
"node_modules/aos/dist/aos.js"
65-
]
65+
],
66+
"define": {
67+
"MINA_WEBNODE_BOOTNODES": "\"\"",
68+
"MINA_WEBNODE_SEED_URLS": "\"\""
69+
}
6670
},
6771
"configurations": {
6872
"production": {

frontend/src/app/core/services/web-node.service.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,13 @@ export class WebNodeService {
161161
if (typeof this.webNodeNetwork === 'number') {
162162
const url = `${window.location.origin}/clusters/${this.webNodeNetwork}/`;
163163
return {
164-
seeds: url + 'seeds',
164+
seedUrls: [url + 'seeds'],
165165
genesisConfig: url + 'genesis/config',
166166
};
167167
} else {
168168
return {
169-
seeds:
170-
'https://bootnodes.minaprotocol.com/networks/devnet-webrtc.txt',
169+
seedUrls: CONFIG.globalConfig.webNodeSeedUrls,
170+
fixedSeeds: CONFIG.globalConfig.webNodeBootNodes,
171171
};
172172
}
173173
})();
@@ -184,7 +184,14 @@ export class WebNodeService {
184184
privateKey = null;
185185
}
186186

187-
return from(wasm.run(privateKey, urls.seeds, urls.genesisConfig));
187+
return from(
188+
wasm.run(
189+
privateKey,
190+
urls.seedUrls,
191+
urls.fixedSeeds,
192+
urls.genesisConfig,
193+
),
194+
);
188195
}),
189196
tap((webnode: any) => {
190197
any(window).webnode = webnode;

frontend/src/app/shared/constants/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function getFirstFeature(
5656
console.log('getFirstFeature called with config:', {
5757
config,
5858
'CONFIG.configs': CONFIG.configs,
59+
globalConfig: CONFIG.globalConfig,
5960
});
6061

6162
if (Array.isArray(config?.features)) {

frontend/src/app/shared/types/core/environment/mina-env.type.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ export interface MinaEnv {
5555
features?: FeaturesConfig;
5656
/** GraphQL endpoint URL for blockchain queries */
5757
graphQL?: string;
58+
59+
/** For WebNodes, optionally supply HTTP(S) URLs to fetch bootnodes from */
60+
webNodeSeedUrls?: Readonly<string[]>;
61+
62+
/** For WebNodes, optionally supply multiaddrs of known bootnodes */
63+
webNodeBootNodes?: Readonly<string[]>;
5864
};
5965
}
6066

frontend/src/environments/environment.webnode-local.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
import { MinaEnv } from '@shared/types/core/environment/mina-env.type';
22

3+
/** Substituted on launch of docker container from MINA_WEBNODE_SEED_URLS by `ng build` */
4+
declare const MINA_WEBNODE_SEED_URLS: string;
5+
6+
/** Default list of seed URLs if MINA_WEBNODE_SEED_URLS isn't specified */
7+
const defaultWebNodeSeedUrls: Readonly<string[]> = [
8+
'https://bootnodes.minaprotocol.com/networks/devnet-webrtc.txt',
9+
'/webnode/pkg/devnet-webrtc.txt',
10+
];
11+
12+
/** Substituted on launch of docker container from MINA_WEBNODE_BOOTNODES by `ng build` */
13+
declare const MINA_WEBNODE_BOOTNODES: string;
14+
15+
/** Default list of bootnodes if MINA_WEBNODE_BOOTNODES is unspecified */
16+
const defaultWebNodeBootNodes: Readonly<string[]> = [
17+
// example:
18+
// "/2az589QvS6i3EJiVKUfVHCkyqf4khGy9PjQF7nSQuveF27wp7xX/https/mina-rust-seed-1.gcp.o1test.net/443",
19+
];
20+
21+
function commaSeparatedEnv(
22+
envVal: string,
23+
fallback: Readonly<string[]>,
24+
): Readonly<string[]> {
25+
const envTrimmed = envVal.trim();
26+
if (envTrimmed.length !== 0) {
27+
const envValue = envTrimmed.split(',').map(s => s.trim());
28+
return envValue;
29+
}
30+
31+
return fallback;
32+
}
33+
334
export const environment: Readonly<MinaEnv> = {
435
production: true,
536
identifier: 'Web Node FE',
@@ -15,6 +46,14 @@ export const environment: Readonly<MinaEnv> = {
1546
mempool: [],
1647
benchmarks: ['wallets'],
1748
},
49+
webNodeSeedUrls: commaSeparatedEnv(
50+
MINA_WEBNODE_SEED_URLS ?? '',
51+
defaultWebNodeSeedUrls,
52+
),
53+
webNodeBootNodes: commaSeparatedEnv(
54+
MINA_WEBNODE_BOOTNODES ?? '',
55+
defaultWebNodeBootNodes,
56+
),
1857
},
1958
configs: [
2059
{

node/web/src/lib.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg(target_family = "wasm")]
22

3-
use ::node::transition_frontier::genesis::GenesisConfig;
3+
use ::node::{core::log, transition_frontier::genesis::GenesisConfig};
44
pub use mina_node_common::*;
55

66
mod rayon;
@@ -28,7 +28,7 @@ fn main() {
2828
thread::main_thread_init();
2929
wasm_bindgen_futures::spawn_local(async {
3030
console_error_panic_hook::set_once();
31-
tracing::initialize(tracing::Level::INFO);
31+
tracing::initialize(tracing::Level::DEBUG);
3232

3333
init_rayon().await.unwrap();
3434
});
@@ -77,15 +77,22 @@ fn parse_bp_key(key: JsValue) -> Option<AccountSecretKey> {
7777
#[wasm_bindgen]
7878
pub async fn run(
7979
block_producer: JsValue,
80-
seed_nodes_url: Option<String>,
80+
seed_nodes_urls: Option<Vec<String>>,
81+
seed_nodes_fixed: Option<Vec<String>>,
8182
genesis_config_url: Option<String>,
8283
) -> RpcSender {
8384
let block_producer = parse_bp_key(block_producer);
8485

8586
let (rpc_sender_tx, rpc_sender_rx) = ::node::core::channels::oneshot::channel();
8687
let _ = thread::spawn(move || {
8788
wasm_bindgen_futures::spawn_local(async move {
88-
let mut node = setup_node(block_producer, seed_nodes_url, genesis_config_url).await;
89+
let mut node = setup_node(
90+
block_producer,
91+
seed_nodes_urls,
92+
seed_nodes_fixed,
93+
genesis_config_url,
94+
)
95+
.await;
8996
let _ = rpc_sender_tx.send(node.rpc());
9097
node.run_forever().await;
9198
});
@@ -98,7 +105,8 @@ pub async fn run(
98105

99106
async fn setup_node(
100107
block_producer: Option<AccountSecretKey>,
101-
seed_nodes_url: Option<String>,
108+
seed_nodes_urls: Option<Vec<String>>,
109+
seed_nodes_fixed: Option<Vec<String>>,
102110
genesis_config_url: Option<String>,
103111
) -> mina_node_common::Node<NodeService> {
104112
let block_verifier_index = BlockVerifier::make().await;
@@ -119,18 +127,34 @@ async fn setup_node(
119127
.work_verifier_index(work_verifier_index.clone());
120128

121129
// TODO(binier): refactor
122-
if let Some(seed_nodes_url) = seed_nodes_url {
123-
let peers = ::node::core::http::get_bytes(&seed_nodes_url)
124-
.await
125-
.expect("failed to fetch seed nodes");
126-
node_builder.initial_peers(
127-
String::from_utf8_lossy(&peers)
128-
.split("\n")
129-
.filter(|s| !s.trim().is_empty())
130-
.map(|s| s.trim().parse().expect("failed to parse seed node addr")),
131-
);
130+
let mut all_raw_peers = seed_nodes_fixed.unwrap_or_default();
131+
if let Some(seed_nodes_urls) = seed_nodes_urls {
132+
for seed_nodes_url in seed_nodes_urls {
133+
let peers = ::node::core::http::get_bytes(&seed_nodes_url).await;
134+
match peers {
135+
Ok(s) => {
136+
log::info!("Successfully fetched peers from {seed_nodes_url}");
137+
all_raw_peers.extend(String::from_utf8_lossy(&s).split("\n").map(String::from));
138+
}
139+
Err(e) => {
140+
log::error!("Failed to fetch peers from {seed_nodes_url}: {e}");
141+
}
142+
}
143+
}
132144
}
133145

146+
node_builder.initial_peers(
147+
all_raw_peers
148+
.iter()
149+
.map(|s| s.trim())
150+
.filter(|s| !s.is_empty())
151+
.flat_map(|s| s.parse().ok())
152+
.map(|p| {
153+
log::debug!("Using peer: {p:?}");
154+
p
155+
}),
156+
);
157+
134158
if let Some(bp_key) = block_producer {
135159
thread::spawn(move || {
136160
BlockProver::make(Some(block_verifier_index), Some(work_verifier_index));

0 commit comments

Comments
 (0)