Skip to content

Instantly share code, notes, and snippets.

@michielbdejong
Last active June 15, 2017 16:40
Show Gist options
  • Save michielbdejong/14f991d14e49f83e0a0f99f77c801e67 to your computer and use it in GitHub Desktop.
Save michielbdejong/14f991d14e49f83e0a0f99f77c801e67 to your computer and use it in GitHub Desktop.

PluginBackend

The backend parameter is an object of the abstract type PluginBackend:

interface PluginBackend {
  getTransferLog(options): TransferLog
}

interface TransferLogOptions {
  maximum: string | null, // Maximum allowed balance (or null if unlimited)
  minimum: string | null, // Minimum allowed balance (or null if unlimited)
}

interface TransferLog {
  async setMaximum(n: string): void
  async setMinimum(n: string): void
  async getMaximum(): string
  async getMinimum(): string
  
  async getBalance(): string

  async get(transferId: string): Promise<TransferWithInfo> // Asynchronously retrieve a transfer from the persistent store
  async prepare(transfer: Transfer, isIncoming: boolean): Promise<void> // Asynchronously prepare a transfer in the persistent store
  async fulfill(transferId: string, fulfillment: string): Promise<void> // Set transfer state to fulfilled
  async cancel(transferId: string): Promise<void> // Set transfer state to canceled
  async cancelExpired(now: DateTime): Promise<void> // cancels all prepared transfers whose `.expiresAt` is before now
}

interface TransferWithInfo {
  // see Ledger Plugin Interface, plus:
  direction: 'incoming' (counts towards upper estimate while prepared) or 'outgoing' (counts towards lower estimate while prepared)
  fulfillment: string
  state: 'prepared', 'fulfilled', or 'cancelled'
  transfer: Transfer
}

At any time there is a range of possible future balance, depending on which prepared transfers will be fulfilled, and which ones will be rejected. The conditions for successfully preparing a new transfer are:

balance + SUM(incomingPrepared) <= maxBalance
balance - SUM(outgoingPrepared) >= minBalance

When a transfer is fulfilled, the balance is updated:

balance += incomingTransfer.amount
balance -= outgoingTransfer.amount

If a transfer is rejected, nothing happens to the balance, but for both fulfilling and rejecting, the transfer in question is removed from the set of prepared transfers.

Outgoing settlements are modeled as incoming transfers, and vice versa.

The currently existing key-value store will still exist, and will become multi-process shared.

We can imagine several implementations of this interface:

  • MockPluginBackend - In-memory backend for unit tests or development
  • SequelizePluginBackend - Simple single-process backend for ILP Kit
  • KafkaPluginBackend - More sophisticated and scalable future backend for multi-process environments
@michielbdejong
Copy link
Author

what should prepare throw if:

  • over/under balance
  • already exists, and is same
  • already exists, and is different

what should fulfill throw if:

  • txid not found
  • already fulfilled - with same/different ;)
  • already cancelled

what should cancel throw if:

  • txid not found
  • already fulfilled
  • already cancelled

@michielbdejong
Copy link
Author

just use the error classes that we already have in the Ledger Plugin Interface

@sharafian
Copy link

Should the backend support Infinity and -Infinity as min/max balances?

@sharafian
Copy link

I think rejectionReason should be part of the TransferWithInfo interface

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment