🔁 Refresh channel accounts section - #2703
Open
JFWooten4 wants to merge 10 commits into
Open
Conversation
Co-authored-by: Codex <noreply@openai.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Expands the channel accounts guide with architecture, security, throughput, and multi-SDK implementation guidance.
Changes:
- Adds diagrams and channel-account concepts.
- Adds Python, JavaScript, Java, and Go examples.
- Documents rotation, fees, capacity, and operational considerations.
Recommendation: NEEDS-CHANGES — fix the non-runnable SDK examples, unsafe rotation logic, and inaccurate fee/capacity guidance.
Comments suppressed due to low confidence (8)
docs/build/guides/transactions/channel-accounts.mdx:129
StellarSdkis not defined by the destructuring import. Use the importedOperationsymbol here as well.
transaction2.addOperation(StellarSdk.Operation.payment({
docs/build/guides/transactions/channel-accounts.mdx:475
- This second Java tab also uses the removed
Transaction.Builderandnew PaymentOperation.Builder(...)APIs, so it cannot compile with Java SDK 4.x. Migrate it toTransactionBuilderandPaymentOperation.builder()before publishing the refreshed guide.
Transaction.Builder transactionBuilder = new Transaction.Builder(channelAccount, Network.TESTNET)
.setBaseFee(Transaction.MIN_BASE_FEE);
for (String recipient : allRecipients.get(i)) {
transactionBuilder.addOperation(
new PaymentOperation.Builder(recipient, AssetTypeNative.INSTANCE, "10")
.setSourceAccount(primaryKeypair.getAccountId())
docs/build/guides/transactions/channel-accounts.mdx:714
- This JavaScript loop has the same rotation deadlock: once every channel is
active, no code marks one available until after this loop exits, which cannot happen while recipients remain. Process and await each wave before assigning another batch.
while (recipientIndex < allRecipients.length) {
for (const channelData of channelAccountsTracker) {
if (recipientIndex >= allRecipients.length) break;
if (channelData.state === "available") {
channelData.state = "active";
docs/build/guides/transactions/channel-accounts.mdx:878
- This Go loop also deadlocks after one batch per channel because channel states are reset only in the submission loop below. If recipients remain after every channel becomes active, neither index nor state can change.
for recipientIndex < len(allRecipients) {
for _, channelData := range channelAccountsTracker {
if recipientIndex >= len(allRecipients) {
break
}
if channelData["state"] == "available" {
docs/build/guides/transactions/channel-accounts.mdx:783
- The Java rotation loop cannot handle more than one batch per channel: after all channels become
active, no state is reset until the later submission loop, so thiswhileloop has no way to make progress. Submit and confirm each wave before continuing allocation.
while (recipientIndex < allRecipients.length) {
for (ChannelAccount channelData : channelAccountsTracker) {
if (recipientIndex >= allRecipients.length) break;
if (channelData.state.equals("available")) {
channelData.state = "active";
docs/build/guides/transactions/channel-accounts.mdx:759
- Even after awaiting submission, this unconditional release is unsafe on rejection or an unknown transport outcome: the local account sequence was advanced when the transaction was built, but the network may not have consumed it. Query/reload the channel account and reconcile the transaction before setting it available.
} finally {
channelData.state = "available";
docs/build/guides/transactions/channel-accounts.mdx:823
- This releases the Java channel even when submission failed or its outcome is unknown. Because transaction construction advances the local account sequence, the next build can use a sequence that does not match the network; reconcile/reload the account before making it available.
} finally {
txBundle.channelData.state = "available";
docs/build/guides/transactions/channel-accounts.mdx:943
- This marks the channel available after both success and failure without reconciling its sequence. When submission fails or times out,
IncrementSequenceNummay have advanced only the local account, so reusing it can produce a sequence gap. Reload/verify the network account before release on non-confirmed outcomes.
output.channelData["state"] = "available"
Comment on lines
+94
to
+102
| const { | ||
| Server, | ||
| Keypair, | ||
| TransactionBuilder, | ||
| Networks, | ||
| Asset, | ||
| } = require("stellar-sdk"); | ||
|
|
||
| const server = new Server('https://horizon-testnet.stellar.org'); |
Comment on lines
+162
to
+166
| Transaction.Builder transactionBuilder1 = new Transaction.Builder(sourceAccount, Network.TESTNET) | ||
| .setBaseFee(100).set_timeout(3600); | ||
|
|
||
| Transaction.Builder transactionBuilder2 = new Transaction.Builder(sourceAccount, Network.TESTNET) | ||
| .setBaseFee(100).set_timeout(3600); |
Comment on lines
+881
to
+883
| sourceAccount := channelData["account"].(*txnbuild.SimpleAccount) | ||
| txBundle := txnbuild.TransactionParams{ | ||
| SourceAccount: sourceAccount, |
|
|
||
| In our example, we assume the bulk payment operations greatly exceed a single transaction, must occur promptly, and come pre-signed by $A_P$. Here, the main constraint is network capacity itself, as referenced earlier with payment channels. Accordingly, it is best practice to considerately send channel transactions based on how much you want to pay in fees. | ||
|
|
||
| If you fill up the ledger with all of your own transactions, you can expect to pay [exponentially-higher fees](../../../learn/fundamentals/fees-resource-limits-metering.mdx#surge-pricing) than dynamic bundle sizes which spread operations out over time. This chiefly depends on the rate you want to submit transactions. As long as you aren't consistently above 100 operations per ledger, each channel can just submit a transaction each ledger. |
|
|
||
| :::note Block Size | ||
|
|
||
| You can create as many channel accounts as needed to maintain your desired transaction rate. However, one ledger [can only fit](https://stellar.expert/explorer/public/protocol-history) 1,000 operations from all peers. To keep [fees](../../../learn/fundamentals/fees-resource-limits-metering.mdx#inclusion-fee) within reason and minimize congestion, it is best practice to limit yourself to 300 operations per ledger. For higher throughput in non-emergency applications, consider using other scaling solutions like [Starlight](../../../learn/glossary.mdx#starlight). |
Comment on lines
+692
to
+693
| finally: | ||
| channelData["state"] = "available" |
|
|
||
| ### Fee Sponsorships | ||
|
|
||
| While we've discussed sending lumens directly to the channel accounts, you can also have transaction fees sponsored by the primary account. In a [custodial solution](../../../platforms/anchor-platform/admin-guide/assets-and-client-wallets.mdx), you may prefer that channel accounts hold no assets at all, maintaining trustlines with [sponsored reserves](./sponsored-reserves.mdx) for example. While you can use payments from $A_P$ to $A_C$ to cover fees each transaction, it is best practice to simply leave channels with adequate funding. |
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
from #723