Fee Bump Transactions Explained

Tyler van der Hoeven
Stellar Community
Published in
7 min readJun 18, 2020

Stellar is constantly evolving and improving through a series of protocol releases. The most recent release — Protocol 13 —introduced an incredibly powerful new feature: fee bump transactions. In this article, we’ll look at transactions on Stellar, the costs involved in submitting them, and some problems that could arise submitting transactions pre-Protocol 13. Then we’ll show how fee bump transactions solve them.

TL;DR watch this.

Transactions on Stellar are boxes containing anywhere from 1 to 100 operations. Payments, trustline creation, offers, and options are all examples of operations that can be packaged inside a transaction. For a transaction to be submitted to the network for execution on the ledger, two consumables must be spent: a fee and a sequence number.

Fees are pretty easy to understand: they act as a spam deterrent, and allow the network to best serve its primary purpose while dis-incentivizing everything else. Fees allow for focus: pay the transaction fee and the network will execute your operations.

Sequence numbers are the lesser known of the pair, and they’re often a wrench in an otherwise well-oiled machine when you’re trying to create a scalable, profitable ,and successful business on Stellar. Sequence numbers are pretty similar to API nonces or one-time use tokens: they protect against replay or double-spend scenarios where two or more machines execute identical operations in different transactions at the same time.

What does that mean? Imagine the Stellar network as a bank (which it’s not, btw): there’s a long counter with several tellers lined up at their windows ready to receive customer requests. Every 5 seconds each teller receives the next client in line, everyone at the desk makes their request, and the tellers all execute those requests. They repeat the same process again with the next clients in line.

You are a grifter (naturally), and you enter the bank with a carefully prepared and rehearsed scheme in mind: right as a 5-second cycle closes, you run up to an open window and input a request to withdraw $100 from your account. The teller accepts the request, and begins looking up your account to prepare to adjust your balance and give you your $100. While that teller is working, you rush over to another open window and make the same request to another teller. They, too, begin looking up your account. Each teller sees you have $100 in your account right now, and each dutifully reduces your balance to $0 and slides a crisp $100 under the glass. As the 5-second cycle closes, before the error can be caught, you walk away with $200.

This scenario is what sequence numbers protect against. When the first teller looks up your account, they include an account sequence number saying they are about to withdraw $100 for sequence X. If you try to use the same X sequence number when the next teller looks up your account, they get an error notifying them that the sequence number is already in use. The only way you can get around this is to quickly pick up a new ticket number for sequence number X+1. At this point, however, the second teller will see a withdraw request for $100 was made in the previous sequence, which would put your balance at $0. You wouldn’t have the money to complete this additional request, so the teller rejects it. Sequence numbers keep accounts running in sequential order where each intention is signed with a “ticket number,” disabling interceptive duplication or replays.

Fees and sequence numbers are both essential features of the Stellar protocol, but that doesn’t stop them from hanging around to harass you as you attempt to run non-nefarious actions on the Stellar blockchain. Let’s consider a few valid scenarios where these features can spoil an otherwise flawless application.

Fee & Balance Issue

Bob and Alice each have 100 XLM; Bob wants to pay Alice 10. You’d think Bob would go from 100 → 90 and Alice would go from 100 → 110; however, due to fees Bob actually ends up somewhere around ~89.99999. That may be acceptable to Bob, but in many scenarios you want to operate in a “fee-less” environment — or rather have your fees paid by someone else.

That “someone else” is what the Stellar ecosystem calls a fee channel account. A fee channel account allows a bank, business, or app to pay the fees on behalf of their users to make a more enticing and user-friendly product.

Fee Channel Solution & Issue

Armed with the understanding that a transaction fee can be paid by a different account that the source account for the operations it contains, we have what we need to begin using a fee channel flow. The basic idea: route transaction fees through the fee channel while leaving the source accounts for operations as-is. One account creates an operation; another account pays the fee to execute it. If you source all outgoing transactions from the fee channel account — and thereby pay the transaction fee for all operations — you’ve achieved the dream of a “fee-less” business model for your users.

Before you celebrate, however… remember how we started at the bank, talking about sequence numbers? It turns out they’re going to bite us in the butt if our fee channel business model reaches any sort of scale.

Imagine 5 users submit a transaction with the fee channel as the source account within the same ~5 second ledger time period. Thanks to the sequence number guardian, only one transaction will actually be able to successfully submit. The other four will be attempting to replay that same fee channel sequence number, which will, and should, fail.

You can try and get around the sequence number issue in clever and convoluted ways. For instance, you could intelligently guess an order, and bump the sequence numbers artificially on the fee-channel receiving side. However, you’re going to need to get the user to re-sign the transaction since what they generated and what the fee channel submits are now different. Not the best customer experience.

You could also just create and fund a lot of different fee channels so that no single one is likely to receive more than a single request per ~5 seconds. This doesn’t really solve anything at scale, though, as ~5 seconds is a long time when you have a ton of customers, and fee channels will need to hold a non-trivial amount of XLM to work.

Alternatively, you could rate limit incoming requests —and map that to the fee-channel sequence number — but if any one of those transactions winds up invalid and un-submitted, any subsequent transaction in the queue will be ahead of the current fee channel sequence number and thus invalid. You could try to keep up via forced sequence number bump operations, but that gets really messy really quickly and needlessly throttles the whole system.

You could also scrap the whole flow and just retroactively pay users back for fees in batches at set intervals. You get high throughput since each user is consuming their own sequence number, and you’re essentially fee-free in that users are eventually paid back. However, the pay back method requires a lot of engineering to keep track of everyone’s debts and credits and to ensure repayments are made in a timely, flawless manner. It also requires that your users already have XLM in their account, which means you can’t build a product that appeals to the non-crypto fluent.

A final option would be intelligent operation batching of user submissions into larger transactions to try and combat throughput with efficiencies. However, this kind of approach tends towards a custodial solution with a centralized single point of failure.

Ultimately, fee channels weren’t the best solution. The world deserves better.

Fee Bump Solution

See how it’s a transaction inside a transaction? Pretty meta huh? The outer transaction pays the fee; the inner transaction pays the sequence number.

Explore the code used to generate the above snippet here.

You can play around with these concepts here.

Click here for a more detailed technical deep dive into fee bump transactions.

Click here to read about other Protocol 13 improvements.

For more information about Stellar and the future of decentralized finance subscribe to our podcast and join our Keybase team.

--

--

Tyler van der Hoeven
Stellar Community

Engineering better financial futures @StellarOrg through funding, education and innovation. I write my own words. — “Work, and stuff will happen.”