Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Channel Payments Design #596

Open
reecexlm opened this issue Feb 22, 2022 · 3 comments
Open

Channel Payments Design #596

reecexlm opened this issue Feb 22, 2022 · 3 comments
Assignees
Labels
design Design the feature

Comments

@reecexlm
Copy link

reecexlm commented Feb 22, 2022

Purpose:
Based on results from load testing deposit transaction submission in Polaris (#589), it can be seen that transaction throughput is currently limited by Polaris only being able to submit one transaction at a time.

With the addition of channel accounts, Polaris will be be able to submit transactions to the Stellar Network in parallel (based on the number of channel accounts used).

Creating / Importing Channel Accounts Into Polaris
Channel Accounts will be created/imported into Polaris via a script. The script can be executed similar to existing Django-Polaris commands (examples below).
The secret key of the channel accounts will be encrypted in the database the same way distribution seeds are currently encrypted for Assets.

Script Features:

  • add a distribution base account (responsible for paying transaction fees for channel accounts - fee bumps)
  • create channel accounts and fund them via friendbot (testnet)
  • create channel accounts and fund them via a distribution account
  • write the created channel accounts public/secret keys into the database
  • delete all channel accounts from the database
  • create an Asset in Polaris (instead of having to do it manually via a python shell)
  • delete an Asset in Polaris

Create N channel accounts on the testnet
python manage.py polaris-tool --action create-channel-accounts --count <count> --testnet true
Create N channel accounts on the mainnet
python manage.py polaris-tool --action create-channel-accounts --count <count> --distribution-seed <distribution_seed>
Delete all channel accounts from the database
python manage.py polaris-tool --action delete-channel-accounts
Create an Asset in Polaris
python manage.py polaris-tool --action create-asset --asset-name <asset_name> --issuer <issuer> --<distribution_seed> --sep6-enabled true --deposit-enabled true
Delete an Asset in Polaris
python manage.py polaris-tool --action delete-asset --asset-name <asset_name>

Polaris changes:
Add a polaris_channel_accounts table to the database with public key and secret (encrypted) columns.

Currently, process_pending_deposits.py is the only process that submits transactions to the Stellar Network and this is the case for the foreseeable future. Because of this and for simplicity, it’s proposed that this process will read all the channel accounts into memory at startup and maintain them in memory. process_pending_deposits.py already has a locking mechanism in place that ensures only one instance of it can be running at any given time so we don’t need to worry about another instance using the same channel accounts.

Using Channel Accounts:

Option 1: Bulk Processing
Have a task that periodically gets all transactions from the SUBMIT_TRANSACTIONS_QUEUE and create a “submit transaction” task for each one. Each task will also be assigned a channel account to use. This is more of a “polling” model and transaction processing time will be affected by the polling interval but may be better able to handle large bursts of deposit transactions.

Option 2: Pool of Executors (Preferred Option)
Spawn N “submit transaction” tasks at startup and assign a channel account to each one. The tasks will all consume from the SUBMIT_TRANSACTIONS_QUEUE (asyncio queue where transactions that are ready to be submitted are put in this queue) and block until there is data. This is an “event driven” model and will be optimal for handling a steady flow of deposit transactions but may not be suited for large bursts of deposit transactions since only N “submit transaction” tasks are spawned at startup.

Paying Transaction Fees:

Option 1: Fund All Channel Accounts
Fund all channel accounts with N lumens and have the channel accounts pay transaction fees for the transactions they submit. We will need a way to monitor and maintain the balance of the channel accounts.

Option 2: Fee-Bump (Preferred Option)
Utilize Fee-Bumps, we only need to maintain the lumens balance of one account that will be used to pay the transaction fees on behalf of the channel accounts.

“The source account of the transaction pays the fee and consumes a sequence number. You can then use one common account (your base account) to make the payment operation inside each transaction. The various channel accounts will consume their sequence numbers even though the funds are being sent from your base account.
You will, of course, have to sign the transaction with both the base account key and the channel account key.”

source: https://developers.stellar.org/docs/glossary/fee-bumps/

@reecexlm reecexlm assigned JakeUrban and stfung77 and unassigned JakeUrban Feb 22, 2022
@JakeUrban
Copy link
Contributor

JakeUrban commented Feb 22, 2022

@reecexlm this issue belongs in stellar/django-polaris, can you (or @stfung77) move it there?

@stfung77 stfung77 transferred this issue from stellar/anchor-platform Mar 1, 2022
@JakeUrban
Copy link
Contributor

JakeUrban commented Mar 4, 2022

@stfung77 This is a great write-up.

Command / Script

I'd like to take step back and ask, do we really need this? My gut says "This is what Django's admin UI is for". If you're unfamiliar with the Django Admin UI, check this out.

The reason we haven't used this in the past is because we didn't ever want the login page to be accessible on public instances. But I think it is overly opinionated for Polaris to not provide ModelAdmin. Instead, we should provide these and let anchors decide if / how they want to host the Django Admin UI, where they can create/edit/delete all of Polaris' models.

For example, we could continue running testanchor.stellar.org as-is without any admin UI, but run a private instance of another Django application with Polaris installed that connects to the same database, and this instance could host the admin UI.

Our ops team already has a system we could use for this.

If we do go with the CLI

If we did build this command, I do think we need to redesign the interface.

I suggest we create another command db with the following subcommand / args structure:

  • create
    • account
      • --type (distribution, channel)
      • --seed
      • --sponsor (only for type=channel)
  • delete
    • account
      • <public key positional argument>

I think we should leave creating Asset objects out of scope, because for completeness we should also add the same kind of tool for all relevant models (ex. OffChainAsset).

Channel Accounts

I don't see a reason not to go with option 2.

Paying Transaction Fees

Again, I think option 2 is the clear pick, however using Fee Bump Transactions only pays for tx fees, not for XLM account reserves. If the distribution account also sponsors the channel account's reserves, then each channel account can have 0 XLM.

@stfung77
Copy link
Contributor

stfung77 commented Mar 8, 2022

Discussed with @JakeUrban last week and settled on the following:

@JakeUrban JakeUrban added the design Design the feature label Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design the feature
Projects
None yet
Development

No branches or pull requests

3 participants