Skip to content

Commit

Permalink
feat: added support mid-agreement debit note interval configuration o…
Browse files Browse the repository at this point in the history
…ption

JST-622

Previously this option was taken from the counter proposal made by the
provider.
  • Loading branch information
grisha87 committed Dec 4, 2023
1 parent 3dfbefa commit bda6a92
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
9 changes: 9 additions & 0 deletions src/market/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const DEFAULTS = {
offerFetchingIntervalSec: 20,
expirationSec: 30 * 60, // 30 min
debitNotesAcceptanceTimeoutSec: 2 * 60, // 2 minutes
midAgreementDebitNoteIntervalSec: 2 * 60, // 2 minutes
midAgreementPaymentTimeoutSec: 12 * 60 * 60, // 12 hours
proposalFilter: acceptAllProposalFilter(),
};
Expand All @@ -26,6 +27,7 @@ export class DemandConfig {
public readonly logger?: Logger;
public readonly eventTarget?: EventTarget;
public readonly debitNotesAcceptanceTimeoutSec: number;
public readonly midAgreementDebitNoteIntervalSec: number;
public readonly midAgreementPaymentTimeoutSec: number;

constructor(options?: DemandOptions) {
Expand All @@ -49,6 +51,13 @@ export class DemandConfig {
throw new Error("The debit note acceptance timeout time has to be a positive integer");
}

this.midAgreementDebitNoteIntervalSec =
options?.midAgreementDebitNoteIntervalSec ?? DEFAULTS.midAgreementDebitNoteIntervalSec;

if (!this.isPositiveInt(this.midAgreementDebitNoteIntervalSec)) {
throw new Error("The debit note interval time has to be a positive integer");
}

this.midAgreementPaymentTimeoutSec =
options?.midAgreementPaymentTimeoutSec ?? DEFAULTS.midAgreementPaymentTimeoutSec;

Expand Down
23 changes: 19 additions & 4 deletions src/market/demand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,31 @@ export interface DemandOptions {
eventTarget?: EventTarget;

/**
* Maximum time for debit note acceptance (in seconds)
* Maximum time for allowed provider-sent debit note acceptance (in seconds)
*
* Accepting debit notes from the provider is used as a health-check of the agreement between these parties.
* Failing to accept 5 debit notes in a row will be considered as a valida reason to terminate the agreement earlier
* than {@link expirationSec} defines.
*
* _Accepting debit notes during a long activity is considered a good practice in Golem Network._
* The SDK will accept debit notes each 2 minutes by default.
*/
debitNotesAcceptanceTimeoutSec?: number;

/**
* The interval between provider sent debit notes to negotiate.
*
* If it would not be defined, the activities created for your demand would
* probably live only 30 minutes, as that's the default value that the providers use to control engagements
* that are not using mid-agreement payments.
*
* _Accepting debit notes during a long activity is considered a good practice in Golem Network._
* The SDK will accept debit notes each 2 minutes.
* As a requestor, you don't have to specify it, as the provider will propose a value that the SDK will simply
* accept without negotiations.
*
* _Accepting payable debit notes during a long activity is considered a good practice in Golem Network._
* The SDK will accept debit notes each 2 minutes by default.
*/
debitNotesAcceptanceTimeoutSec?: number;
midAgreementDebitNoteIntervalSec?: number;

/**
* Maximum time to receive payment for any debit note. At the same time, the minimum interval between mid-agreement payments.
Expand Down
1 change: 1 addition & 0 deletions src/market/factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe("Demand Factory", () => {

// The properties responsible for mid-agreements payments are set
expect(demandRequestBody.properties["golem.com.payment.debit-notes.accept-timeout?"]).toBeDefined();
expect(demandRequestBody.properties["golem.com.scheme.payu.debit-note.interval-sec?"]).toBeDefined();
expect(demandRequestBody.properties["golem.com.scheme.payu.payment-timeout-sec?"]).toBeDefined();
expect(demandRequestBody.properties["golem.srv.comp.expiration"]).toBeDefined();

Expand Down
3 changes: 2 additions & 1 deletion src/market/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ export class DemandFactory {
.addProperty("golem.srv.caps.multi-activity", true)
.addProperty("golem.srv.comp.expiration", Date.now() + this.options.expirationSec * 1000)
.addProperty("golem.node.debug.subnet", this.options.subnetTag)
.addProperty("golem.com.payment.debit-notes.accept-timeout?", this.options.debitNotesAcceptanceTimeoutSec)
.addConstraint("golem.com.pricing.model", "linear")
.addConstraint("golem.node.debug.subnet", this.options.subnetTag);

// Configure mid-agreement payments
builder
.addProperty("golem.com.payment.debit-notes.accept-timeout?", this.options.debitNotesAcceptanceTimeoutSec)
.addProperty("golem.com.scheme.payu.debit-note.interval-sec?", this.options.midAgreementDebitNoteIntervalSec)
.addProperty("golem.com.scheme.payu.payment-timeout-sec?", this.options.midAgreementPaymentTimeoutSec);

return builder.getDecorations();
Expand Down
17 changes: 13 additions & 4 deletions src/market/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,23 @@ export class MarketService {
}

private async isProposalValid(proposal: Proposal): Promise<{ result: boolean; reason?: string }> {
if (!this.allocation) throw new Error("The service has not been started correctly.");
if (!this.allocation) {
throw new Error("The service has not been started correctly.");
}

const timeout = proposal.properties["golem.com.payment.debit-notes.accept-timeout?"];
if (timeout && timeout < this.options.debitNotesAcceptanceTimeoutSec)
if (timeout && timeout < this.options.debitNotesAcceptanceTimeoutSec) {
return { result: false, reason: "Debit note acceptance timeout too short" };
if (!proposal.hasPaymentPlatform(this.allocation.paymentPlatform))
}

if (!proposal.hasPaymentPlatform(this.allocation.paymentPlatform)) {
return { result: false, reason: "No common payment platform" };
if (!(await this.options.proposalFilter(proposal)))
}

if (!(await this.options.proposalFilter(proposal))) {
return { result: false, reason: "Proposal rejected by Proposal Filter" };
}

return { result: true };
}

Expand Down

0 comments on commit bda6a92

Please sign in to comment.