From c34d40ca9d0fdedb721600ae00ff4fa408e1de15 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Wed, 31 Jul 2024 11:36:37 +0200 Subject: [PATCH 1/6] refactor: rename scanned-proposal to scanned-offer to match class name --- src/market/scan/index.ts | 2 +- .../scan/{scanned-proposal.ts => scanned-offer.ts} | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) rename src/market/scan/{scanned-proposal.ts => scanned-offer.ts} (99%) diff --git a/src/market/scan/index.ts b/src/market/scan/index.ts index a6e78b177..852270e48 100644 --- a/src/market/scan/index.ts +++ b/src/market/scan/index.ts @@ -1,3 +1,3 @@ export * from "./types"; export * from "./scan-director"; -export * from "./scanned-proposal"; +export * from "./scanned-offer"; diff --git a/src/market/scan/scanned-proposal.ts b/src/market/scan/scanned-offer.ts similarity index 99% rename from src/market/scan/scanned-proposal.ts rename to src/market/scan/scanned-offer.ts index c0797b28c..fb75e7c9e 100644 --- a/src/market/scan/scanned-proposal.ts +++ b/src/market/scan/scanned-offer.ts @@ -51,33 +51,43 @@ export class ScannedOffer { name: this.properties["golem.node.id.name"] || "", }; } + get transferProtocol() { return this.properties["golem.activity.caps.transfer.protocol"]; } + get cpuBrand() { return this.properties["golem.inf.cpu.brand"]; } + get cpuCapabilities() { return this.properties["golem.inf.cpu.capabilities"]; } + get cpuCores() { return this.properties["golem.inf.cpu.cores"]; } + get cpuThreads() { return this.properties["golem.inf.cpu.threads"]; } + get memory() { return this.properties["golem.inf.mem.gib"]; } + get storage() { return this.properties["golem.inf.storage.gib"]; } + get publicNet() { return this.properties["golem.node.net.is-public"]; } + get runtimeCapabilities() { return this.properties["golem.runtime.capabilities"]; } + get runtimeName() { return this.properties["golem.runtime.name"]; } From c3682bd07a42ef3a56403a31a84c13e094f9d7fb Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Wed, 31 Jul 2024 11:41:20 +0200 Subject: [PATCH 2/6] fix(market): exposed memoryGib and storageGib from ScannedOffer, deprecating old methods --- src/market/scan/scanned-offer.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/market/scan/scanned-offer.ts b/src/market/scan/scanned-offer.ts index fb75e7c9e..56a581d3e 100644 --- a/src/market/scan/scanned-offer.ts +++ b/src/market/scan/scanned-offer.ts @@ -72,11 +72,21 @@ export class ScannedOffer { return this.properties["golem.inf.cpu.threads"]; } + /** @deprecated Use {@link memoryGib} instead */ get memory() { + return this.memoryGib; + } + + get memoryGib() { return this.properties["golem.inf.mem.gib"]; } + /** @deprecated Use {@link storageGib} instead */ get storage() { + return this.storageGib; + } + + get storageGib() { return this.properties["golem.inf.storage.gib"]; } From 94163595b09d86576ced9d040b9de4d00384ded0 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Wed, 31 Jul 2024 11:43:20 +0200 Subject: [PATCH 3/6] feat(market): added offerId to ScannedOffer --- src/market/scan/scanned-offer.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/market/scan/scanned-offer.ts b/src/market/scan/scanned-offer.ts index 56a581d3e..50fd63dee 100644 --- a/src/market/scan/scanned-offer.ts +++ b/src/market/scan/scanned-offer.ts @@ -101,4 +101,15 @@ export class ScannedOffer { get runtimeName() { return this.properties["golem.runtime.name"]; } + + /** + * Get the ID of the offer published by the Provider + * + * Note: + * - this ID will change after the provider refreshes the offer (usually after 1h) + * - this ID will remain unchanged for the same published offer between different scans + */ + get offerId() { + return this.model.offerId; + } } From 56dd57521d5c1c5f79a1e39833140233ead9e277 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Wed, 31 Jul 2024 12:28:54 +0200 Subject: [PATCH 4/6] feat(market): add GPU support properties and payment platform addresses Introduced GAP-35 GPU capability properties to the proposal properties. Added cpuVendor, gpuBrand, offerCreateAt, and paymentPlatformAddresses getters to the ScannedOffer class. --- src/market/proposal/proposal-properties.ts | 27 +++++++++++-- src/market/scan/scanned-offer.ts | 44 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/market/proposal/proposal-properties.ts b/src/market/proposal/proposal-properties.ts index 9503f9830..837c60686 100644 --- a/src/market/proposal/proposal-properties.ts +++ b/src/market/proposal/proposal-properties.ts @@ -20,10 +20,28 @@ export type GenericGolemProtocolPropertyType = Record; + +/** + * Properties defined by GAP-35 + * + * @link https://github.com/golemfactory/golem-architecture/blob/master/gaps/gap-35_gpu_pci_capability/gap-35_gpu_pci_capability.md + */ +export type Gap35GpuSupportProps = Partial<{ + "golem.!exp.gap-35.v1.inf.gpu.model": string; + "golem.!exp.gap-35.v1.inf.gpu.clocks.graphics.mhz": number; + "golem.!exp.gap-35.v1.inf.gpu.clocks.memory.mhz": number; + "golem.!exp.gap-35.v1.inf.gpu.clocks.sm.mhz": number; + "golem.!exp.gap-35.v1.inf.gpu.clocks.video.mhz": number; + "golem.!exp.gap-35.v1.inf.gpu.cuda.cores": number; + "golem.!exp.gap-35.v1.inf.gpu.cuda.enabled": boolean; + "golem.!exp.gap-35.v1.inf.gpu.cuda.version": string; + "golem.!exp.gap-35.v1.inf.gpu.memory.bandwidth.gib": number; + "golem.!exp.gap-35.v1.inf.gpu.memory.total.gib": number; +}>; /** * @link https://github.com/golemfactory/golem-architecture/tree/master/standards/0-commons */ @@ -98,6 +116,7 @@ export type ProposalProperties = StandardComputationPlatformProps & // Attach GAP specific property sets Gap3MidAgreementPaymentProps & + Gap35GpuSupportProps & /** * These are around byt not really specified in any standard * FIXME #yagna - Standardize? diff --git a/src/market/scan/scanned-offer.ts b/src/market/scan/scanned-offer.ts index 50fd63dee..939cf2526 100644 --- a/src/market/scan/scanned-offer.ts +++ b/src/market/scan/scanned-offer.ts @@ -4,6 +4,11 @@ import type { MarketApi } from "ya-ts-client"; type ScannedOfferDTO = MarketApi.OfferDTO; +type PaymentPlatformAddressSet = { + /** The payment platform and address map */ + [paymentPlatform: string]: string | undefined; +}; + export class ScannedOffer { constructor(private readonly model: ScannedOfferDTO) {} @@ -60,6 +65,10 @@ export class ScannedOffer { return this.properties["golem.inf.cpu.brand"]; } + get cpuVendor() { + return this.properties["golem.inf.cpu.vendor"]; + } + get cpuCapabilities() { return this.properties["golem.inf.cpu.capabilities"]; } @@ -72,6 +81,10 @@ export class ScannedOffer { return this.properties["golem.inf.cpu.threads"]; } + get gpuBrand() { + return this.properties["golem.!exp.gap-35.v1.inf.gpu.model"]; + } + /** @deprecated Use {@link memoryGib} instead */ get memory() { return this.memoryGib; @@ -112,4 +125,35 @@ export class ScannedOffer { get offerId() { return this.model.offerId; } + + /** + * The timestamp at which the offer was generated by the Provider + */ + get offerCreateAt() { + return this.model.timestamp; + } + + /** + * Lists down payment addresses on different payment platforms + * + * @example Example return value + * ```json + * { + * "erc20-polygon-glm": "0x8737beea5668595fda9d50e85cae9cad10b4c980", + * "erc20-holesky-tglm:" "0x8737beea5668595fda9d50e85cae9cad10b4c980", + * } + * ``` + */ + get paymentPlatformAddresses(): PaymentPlatformAddressSet { + const platformProps = Object.entries(this.model.properties).filter(([key]) => + key.startsWith("golem.com.payment.platform."), + ); + + const platformAddress = platformProps.map(([key, address]) => [ + key.replace("golem.com.payment.platform.", "").replace(".address", ""), + address, + ]); + + return Object.fromEntries(platformAddress); + } } From 37be0d3470c0c4af7234e441278fae53a6a83dc2 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Wed, 31 Jul 2024 16:50:30 +0200 Subject: [PATCH 5/6] test: applied review remark and added a test --- src/market/scan/scanned-offer.test.ts | 22 ++++++++++++++++++++++ src/market/scan/scanned-offer.ts | 17 +++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 src/market/scan/scanned-offer.test.ts diff --git a/src/market/scan/scanned-offer.test.ts b/src/market/scan/scanned-offer.test.ts new file mode 100644 index 000000000..946cfa9d8 --- /dev/null +++ b/src/market/scan/scanned-offer.test.ts @@ -0,0 +1,22 @@ +import { ScannedOffer } from "./scanned-offer"; + +describe("Scanned Offer", () => { + test("Returns payment platform address information", async () => { + const offer = new ScannedOffer({ + offerId: "example-id", + properties: { + "golem.com.payment.platform.erc20-polygon-glm.address": "0xPolygonAddress", + "golem.com.payment.platform.erc20-holesky-tglm.address": "0xHoleskyAddress", + "golem.com.payment.platform.nonsense": "0xNonsense", + "some.other.prop": "with-a-value", + }, + timestamp: new Date().toISOString(), + providerId: "provider-id", + constraints: "", + }); + + expect(offer.paymentPlatformAddresses["erc20-polygon-glm"]).toEqual("0xPolygonAddress"); + expect(offer.paymentPlatformAddresses["erc20-holesky-tglm"]).toEqual("0xHoleskyAddress"); + expect(Object.entries(offer.paymentPlatformAddresses).length).toEqual(2); + }); +}); diff --git a/src/market/scan/scanned-offer.ts b/src/market/scan/scanned-offer.ts index 939cf2526..4388d889a 100644 --- a/src/market/scan/scanned-offer.ts +++ b/src/market/scan/scanned-offer.ts @@ -145,14 +145,15 @@ export class ScannedOffer { * ``` */ get paymentPlatformAddresses(): PaymentPlatformAddressSet { - const platformProps = Object.entries(this.model.properties).filter(([key]) => - key.startsWith("golem.com.payment.platform."), - ); - - const platformAddress = platformProps.map(([key, address]) => [ - key.replace("golem.com.payment.platform.", "").replace(".address", ""), - address, - ]); + const propRegex = /golem.com.payment.platform.([a-z0-9-]+).address/; + const platformProps = Object.entries(this.model.properties).filter(([key]) => key.match(propRegex)); + + const platformAddress = platformProps + .map<[string, string]>(([key, address]) => { + const match = key.match(propRegex); + return [match ? match[1] : "", address]; + }) + .filter(([key]) => !!key); return Object.fromEntries(platformAddress); } From 4c3a61c6ba3d596ffd6319113caecd251bce09f1 Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Thu, 1 Aug 2024 10:16:40 +0200 Subject: [PATCH 6/6] chore: applied review remarks --- src/market/scan/scanned-offer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/market/scan/scanned-offer.ts b/src/market/scan/scanned-offer.ts index 4388d889a..1f1a22726 100644 --- a/src/market/scan/scanned-offer.ts +++ b/src/market/scan/scanned-offer.ts @@ -145,10 +145,9 @@ export class ScannedOffer { * ``` */ get paymentPlatformAddresses(): PaymentPlatformAddressSet { - const propRegex = /golem.com.payment.platform.([a-z0-9-]+).address/; - const platformProps = Object.entries(this.model.properties).filter(([key]) => key.match(propRegex)); + const propRegex = /golem\.com\.payment\.platform\.([a-z0-9-]+)\.address/; - const platformAddress = platformProps + const platformAddress = Object.entries(this.model.properties) .map<[string, string]>(([key, address]) => { const match = key.match(propRegex); return [match ? match[1] : "", address];