Skip to content

Commit c78a6ab

Browse files
authored
Merge branch 'master' into scx1332/update_payment7
2 parents fe220ea + 0acd1be commit c78a6ab

File tree

26 files changed

+1045
-29
lines changed

26 files changed

+1045
-29
lines changed

.github/workflows/integration-test.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
7979
- name: Build binaries
8080
run: |
81-
cargo build --features static-openssl --target x86_64-unknown-linux-musl -p yagna -p ya-exe-unit -p gftp -p golemsp -p ya-provider -p erc20_processor
81+
cargo build --features require-consent,static-openssl --target x86_64-unknown-linux-musl -p yagna -p ya-exe-unit -p gftp -p golemsp -p ya-provider -p erc20_processor
8282
8383
- name: Move target binaries
8484
run: |
@@ -133,6 +133,7 @@ jobs:
133133
- name: Check installed binaries
134134
run: |
135135
yagna --version
136+
yagna consent allow-all
136137
erc20_processor --version
137138
138139
- name: Run test

.github/workflows/release.yml

+7-7
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,9 @@ jobs:
205205
- name: Build macos
206206
if: matrix.os == 'macos'
207207
run: |
208-
cargo build --release --features static-openssl
208+
cargo build --release --features require-consent,static-openssl
209209
cargo build --bin gftp -p gftp --release
210-
cargo build --bin golemsp -p golemsp --release
210+
cargo build --bin golemsp --features require-consent -p golemsp --release
211211
cargo build --bin ya-provider -p ya-provider --release
212212
cargo build --bin exe-unit -p ya-exe-unit --release --features openssl/vendored
213213
- name: Build windows
@@ -216,18 +216,18 @@ jobs:
216216
vcpkg install openssl:x64-windows-static
217217
vcpkg integrate install
218218
219-
cargo build --release
219+
cargo build --release --features require-consent
220220
cargo build --bin gftp -p gftp --release
221-
cargo build --bin golemsp -p golemsp --release
221+
cargo build --bin golemsp --features require-consent -p golemsp --release
222222
cargo build --bin ya-provider -p ya-provider --release
223223
cargo build --bin exe-unit -p ya-exe-unit --release
224224
225225
- name: Build linux
226226
if: matrix.os == 'ubuntu'
227227
run: |
228-
cargo build --release --features static-openssl --target x86_64-unknown-linux-musl
228+
cargo build --release --features require-consent,static-openssl --target x86_64-unknown-linux-musl
229229
(cd core/gftp && cargo build --bin gftp -p gftp --features bin --release --target x86_64-unknown-linux-musl)
230-
(cd golem_cli && cargo build --bin golemsp -p golemsp --release --features openssl/vendored --target x86_64-unknown-linux-musl)
230+
(cd golem_cli && cargo build --bin golemsp -p golemsp --release --features require-consent,openssl/vendored --target x86_64-unknown-linux-musl)
231231
(cd agent/provider && cargo build --bin ya-provider -p ya-provider --release --features openssl/vendored --target x86_64-unknown-linux-musl)
232232
(cd exe-unit && cargo build --bin exe-unit -p ya-exe-unit --release --features openssl/vendored --target x86_64-unknown-linux-musl)
233233
- name: Pack
@@ -310,7 +310,7 @@ jobs:
310310
-p golemsp
311311
-p gftp
312312
--release
313-
--features static-openssl
313+
--features require-consent,static-openssl
314314
--target aarch64-unknown-linux-musl
315315
316316
- name: Pack

.github/workflows/unit-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@ jobs:
7373
uses: actions-rs/cargo@v1
7474
with:
7575
command: test
76-
args: --workspace --exclude=["./agent/provider/src/market"] --locked
76+
args: --workspace --features require-consent --exclude=["./agent/provider/src/market"] --locked

Cargo.lock

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ default = ['erc20-driver', 'gftp/bin']
1414
dashboard = ['rust-embed', 'mime_guess']
1515
dummy-driver = ['ya-dummy-driver']
1616
erc20-driver = ['ya-erc20-driver']
17+
require-consent = ['ya-utils-consent/require-consent']
1718
static-openssl = ["openssl/vendored", "openssl-probe"]
1819
tos = []
1920
framework-test = [
@@ -56,6 +57,7 @@ ya-service-api-interfaces.workspace = true
5657
ya-service-api-web.workspace = true
5758
ya-service-bus = { workspace = true }
5859
ya-sgx.path = "core/sgx"
60+
ya-utils-consent.workspace = true
5961
ya-utils-path.workspace = true
6062
ya-utils-futures.workspace = true
6163
ya-utils-process = { workspace = true, features = ["lock"] }
@@ -262,6 +264,7 @@ gftp = {version = "0.4.1", path = "core/gftp"}
262264
hex = "0.4.3"
263265
libsqlite3-sys = {version = "0.26.0", features = ["bundled"]}
264266
openssl = "0.10"
267+
promptly = "0.3.0"
265268
rand = "0.8.5"
266269
regex = "1.10.4"
267270
strum = {version = "0.24", features = ["derive"]}
@@ -292,6 +295,7 @@ ya-std-utils = { path = "utils/std-utils" }
292295
ya-diesel-utils.path = "utils/diesel-utils"
293296
ya-utils-actix.path = "utils/actix_utils"
294297
ya-core-model = { path = "core/model" }
298+
ya-utils-consent.path = "utils/consent"
295299
ya-utils-path.path = "utils/path"
296300
ya-utils-process.path = "utils/process"
297301

core/identity/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ diesel = { version = "1.4", features = ["sqlite", "r2d2", "chrono"] }
2525
diesel_migrations = "1.4"
2626
ethsign = "0.8"
2727
futures = "0.3"
28-
hex = { workspace = true }
28+
hex.workspace = true
2929
log = "0.4"
30-
promptly = "0.3.0"
30+
promptly.workspace = true
3131
r2d2 = "0.8.8"
3232
rand = "0.8"
3333
rpassword = "3.0.2"

core/metrics/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ya-core-model = { workspace = true, features = ["identity"] }
1414
ya-service-api.workspace = true
1515
ya-service-api-interfaces.workspace = true
1616
ya-service-bus = { workspace = true }
17+
ya-utils-consent = { workspace = true }
1718

1819
awc = "3"
1920
actix-web = { version = "4", features = ["openssl"] }

core/metrics/src/pusher.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use lazy_static::lazy_static;
44
use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
55
use tokio::time::{self, Duration, Instant};
66

7+
use crate::service::export_metrics_for_push;
78
use ya_core_model::identity::{self, IdentityInfo};
89
use ya_service_api::MetricsCtx;
910
use ya_service_bus::typed as bus;
@@ -26,7 +27,7 @@ pub fn spawn(ctx: MetricsCtx) {
2627
log::warn!("Metrics pusher enabled, but no `push_host_url` provided");
2728
}
2829
});
29-
log::info!("Metrics pusher started");
30+
log::debug!("Metrics pusher started");
3031
}
3132

3233
pub async fn push_forever(host_url: &str, ctx: &MetricsCtx) {
@@ -54,22 +55,27 @@ pub async fn push_forever(host_url: &str, ctx: &MetricsCtx) {
5455
let mut push_interval = time::interval_at(start, Duration::from_secs(60));
5556
let client = Client::builder().timeout(Duration::from_secs(30)).finish();
5657

57-
log::info!("Starting metrics pusher on address: {push_url}");
58+
log::info!(
59+
"Metrics will be pushed only if appropriate consent is given, push endpoint: {push_url}"
60+
);
5861
loop {
5962
push_interval.tick().await;
6063
push(&client, push_url.clone()).await;
6164
}
6265
}
6366

6467
pub async fn push(client: &Client, push_url: String) {
65-
let metrics = crate::service::export_metrics().await;
68+
let metrics = export_metrics_for_push().await;
69+
if metrics.is_empty() {
70+
return;
71+
}
6672
let res = client
6773
.put(push_url.as_str())
6874
.send_body(metrics.clone())
6975
.await;
7076
match res {
7177
Ok(r) if r.status().is_success() => {
72-
log::trace!("Metrics pushed: {}", r.status())
78+
log::debug!("Metrics pushed: {}", r.status())
7379
}
7480
Ok(r) if r.status().is_server_error() => {
7581
log::debug!("Metrics server error: {:#?}", r);

core/metrics/src/service.rs

+72-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use actix_web::web::Path;
12
use futures::lock::Mutex;
23
use lazy_static::lazy_static;
34
use std::collections::HashMap;
@@ -7,6 +8,7 @@ use url::Url;
78

89
use ya_service_api::{CliCtx, MetricsCtx};
910
use ya_service_api_interfaces::Provider;
11+
use ya_utils_consent::ConsentScope;
1012

1113
use crate::metrics::Metrics;
1214

@@ -72,6 +74,15 @@ lazy_static! {
7274
static ref METRICS: Arc<Mutex<Metrics>> = Metrics::new();
7375
}
7476

77+
pub async fn export_metrics_filtered_web(typ: Path<String>) -> String {
78+
let allowed_prefixes = typ.split(',').collect::<Vec<_>>();
79+
log::info!("Allowed prefixes: {:?}", allowed_prefixes);
80+
let filter = MetricsFilter {
81+
allowed_prefixes: &allowed_prefixes,
82+
};
83+
export_metrics_filtered(Some(filter)).await
84+
}
85+
7586
impl MetricsService {
7687
pub async fn gsb<C: Provider<Self, CliCtx>>(context: &C) -> anyhow::Result<()> {
7788
// This should initialize Metrics. We need to do this before all other services will start.
@@ -89,35 +100,86 @@ impl MetricsService {
89100
pub fn rest<C: Provider<Self, ()>>(_ctx: &C) -> actix_web::Scope {
90101
actix_web::Scope::new("metrics-api/v1")
91102
// TODO:: add wrapper injecting Bearer to avoid hack in auth middleware
92-
.route("/expose", actix_web::web::get().to(export_metrics))
103+
.route("/expose", actix_web::web::get().to(export_metrics_local))
93104
.route("/sorted", actix_web::web::get().to(export_metrics_sorted))
105+
.route(
106+
"/filtered/{typ}",
107+
actix_web::web::get().to(export_metrics_filtered_web),
108+
)
109+
.route(
110+
"/filtered",
111+
actix_web::web::get().to(export_metrics_for_push),
112+
)
94113
}
95114
}
115+
116+
pub(crate) struct MetricsFilter<'a> {
117+
pub allowed_prefixes: &'a [&'a str],
118+
}
119+
96120
//algorith is returning metrics in random order, which is fine for prometheus, but not for human checking metrics
97-
pub fn sort_metrics_txt(metrics: &str) -> String {
121+
pub fn sort_metrics_txt(metrics: &str, filter: Option<MetricsFilter<'_>>) -> String {
98122
let Some(first_line_idx) = metrics.find('\n') else {
99123
return metrics.to_string();
100124
};
101125
let (first_line, metrics_content) = metrics.split_at(first_line_idx);
102126

103-
let mut entries = metrics_content
127+
let entries = metrics_content
104128
.split("\n\n") //splitting by double new line to get separate metrics
105129
.map(|s| {
106130
let trimmed = s.trim();
107131
let mut lines = trimmed.split('\n').collect::<Vec<_>>();
108132
lines.sort(); //sort by properties
109-
lines.join("\n")
133+
(lines.get(1).unwrap_or(&"").to_string(), lines.join("\n"))
110134
})
111-
.collect::<Vec<String>>();
112-
entries.sort(); //sort by metric name
135+
.collect::<Vec<(String, String)>>();
136+
137+
let mut final_entries = if let Some(filter) = filter {
138+
let mut final_entries = Vec::with_capacity(entries.len());
139+
for entry in entries {
140+
for prefix in filter.allowed_prefixes {
141+
if entry.0.starts_with(prefix) {
142+
log::info!("Adding entry: {}", entry.0);
143+
final_entries.push(entry.1);
144+
break;
145+
}
146+
}
147+
}
148+
final_entries
149+
} else {
150+
entries.into_iter().map(|(_, s)| s).collect()
151+
};
113152

114-
first_line.to_string() + "\n" + entries.join("\n\n").as_str()
153+
final_entries.sort();
154+
155+
first_line.to_string() + "\n" + final_entries.join("\n\n").as_str() + "\n"
156+
}
157+
158+
pub async fn export_metrics_filtered(metrics_filter: Option<MetricsFilter<'_>>) -> String {
159+
sort_metrics_txt(&METRICS.lock().await.export(), metrics_filter)
115160
}
116161

117162
async fn export_metrics_sorted() -> String {
118-
sort_metrics_txt(&METRICS.lock().await.export())
163+
sort_metrics_txt(&METRICS.lock().await.export(), None)
164+
}
165+
166+
pub async fn export_metrics_for_push() -> String {
167+
//if consent is not set assume we are not allowed to push metrics
168+
let stats_consent = ya_utils_consent::have_consent_cached(ConsentScope::Stats)
169+
.consent
170+
.unwrap_or(false);
171+
let filter = if stats_consent {
172+
log::info!("Pushing all metrics, because stats consent is given");
173+
None
174+
} else {
175+
// !internal_consent && !external_consent
176+
log::info!("Not pushing metrics, because stats consent is not given");
177+
return "".to_string();
178+
};
179+
180+
export_metrics_filtered(filter).await
119181
}
120182

121-
pub async fn export_metrics() -> String {
122-
METRICS.lock().await.export()
183+
pub async fn export_metrics_local() -> String {
184+
export_metrics_sorted().await
123185
}

core/serv/src/main.rs

+10
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ use autocomplete::CompleteCommand;
5353

5454
use ya_activity::TrackerRef;
5555
use ya_service_api_web::middleware::cors::AppKeyCors;
56+
use ya_utils_consent::{
57+
consent_check_before_startup, set_consent_path_in_yagna_dir, ConsentService,
58+
};
5659

5760
lazy_static::lazy_static! {
5861
static ref DEFAULT_DATA_DIR: String = DataDir::new(clap::crate_name!()).to_string();
@@ -261,6 +264,8 @@ enum Services {
261264
Activity(ActivityService),
262265
#[enable(gsb, rest, cli)]
263266
Payment(PaymentService),
267+
#[enable(cli)]
268+
Consent(ConsentService),
264269
#[enable(gsb)]
265270
SgxDriver(SgxService),
266271
#[enable(gsb, rest)]
@@ -475,6 +480,7 @@ impl ServiceCommand {
475480
if !ctx.accept_terms {
476481
prompt_terms()?;
477482
}
483+
478484
match self {
479485
Self::Run(ServiceCommandOpts {
480486
api_url,
@@ -541,6 +547,9 @@ impl ServiceCommand {
541547

542548
let _lock = ProcLock::new(app_name, &ctx.data_dir)?.lock(std::process::id())?;
543549

550+
//before running yagna check consents
551+
consent_check_before_startup(false)?;
552+
544553
ya_sb_router::bind_gsb_router(ctx.gsb_url.clone())
545554
.await
546555
.context("binding service bus router")?;
@@ -761,6 +770,7 @@ async fn main() -> Result<()> {
761770

762771
std::env::set_var(GSB_URL_ENV_VAR, args.gsb_url.as_str()); // FIXME
763772

773+
set_consent_path_in_yagna_dir()?;
764774
match args.run_command().await {
765775
Ok(()) => Ok(()),
766776
Err(err) => {

extra/payments/multi_test/payment_test.py

+4
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ def process_erc20():
167167
balance = get_balance()
168168
if balance[public_addrs[0]]["tokenDecimal"] != "0":
169169
raise Exception("Test failed early because of wrong initial balance")
170+
171+
# give consent before running yagna service
172+
run_command(f"{yagna} consent allow-all")
173+
170174
pr = subprocess.Popen([yagna, "service", "run"])
171175
time.sleep(10)
172176

0 commit comments

Comments
 (0)