Channel Payments Design #596
Description
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/