Shared sequencers for Starknet and Madara app chains

Introduction

Today, we are already seeing projects starting to experiment with Madara for their app chains. Pragma, Kakarot, Mangata Finance, and Dojo are just some examples. As long as we believe in the multi-chain future and the power of zk scaling, we will only see many more of these projects in the future. However, the increasing number of app chains also raises questions around

  1. Decentralisation
  2. Composability
  3. Development experience

In this post, I will try to explain the problems that arise due to having a lot of app chains and also pose a possible solution to the problem that I consider elegant and optimal for Madara and Starknet. If you are already well versed with app chains and shared sequencing, feel free to jump to the “Wait, it’s just Polkadot all over again” section.

What happens at 100 app chains?

Let’s say we are in a future where we now have 100 different app chains settling on Ethereum. Let’s address all the problems this will cause.

Fragmented decentralisation

Every app chain will need to solve for decentralisation on its own. Now the decentralisation of app chains is not as necessary as that of L1s mainly because we rely on L1s for security. However, we still need decentralisation to ensure liveliness, censorship resistance and to avoid monopolistic advantages (high fees for example). However, it’s also important to note that If each app chain goes on to solve for decentralisation its own way, this will very quickly lead to fragmentation of validator sets. Each app chain would have to develop economic incentives to onboard new validators. Also, validators would need to select what clients they are comfortable with running. Not to mention the huge barrier to entry this creates for developers to launch their own app chains (vs deploying a smart contract which is just a transaction).

Composability

Composability essentially means cross-app interaction. On Ethereum or Starknet, this just means calling another contract and everything else is handled by the protocol itself. However, with app chains, this becomes much more difficult. Different app chains have their own blocks and consensus mechanisms. Every time you try to try to interact with another app chain, you need to carefully examine the consensus algorithm and the finality guarantees and accordingly set up a cross-chain bridge (directly to the chain or via the L1). If you want to interact with 10 app chains with different designs, you would do this 10 different times.

Development experience

Solving for decentralisation and bridging is not easy. If this is a requirement for every app chain, it will make it very difficult for the usual smart contract developer to ever build his own app chain. Moreover, as every app chain tries to solve these problems in its own ways, we will soon see different standards being followed by different chains making it even more difficult to join the ecosystem.

Shared Sequencers can solve this

Now if you’re following the app chain space, you might have heard of the term “shared sequencers”. It’s the idea of having a common set of validators for all chains that aim to solve the problems mentioned above. This is how it works.

Shared Decentralisation

The very essence of shared sequencers is that you don’t need to have a different set of validators for each app chain or L2. Instead, you can have a really efficient and decentralised set of validators that sequence the blocks for all the chains! Imagine blocks that contain transactions from 100 different app chains. You might be thinking this is going to really bloat up the sequencer as you need to be able to handle execution engines for each app chain.

Well, you don’t!

Since today almost every sequencer is centralized, the sequencer is thought of as a single application that collects transactions, orders them, executes them and posts the results on the L1. However, these jobs can be separated into multiple modular components. For the sake of this explanation, I will divide them into two.

  1. Order engine: This is responsible for sequencing the transactions in a specific order. Once this order has been decided by the order engine, it MUST be followed. This is enforced by committing this order on the L1 and forcing L1 verifiers to check if transactions were executed in the required order.
  2. Rollup engine: The rollup engine is basically everything else the rollup does - collecting transactions from users, executing them, creating proofs and updating the state on the L1. Ideally, this can be broken into more components but we would avoid that for this post.

Here, the ordering engine is the shared sequencer and the rollup engine is basically all the rollup logic. So the transaction lifecycle looks like this

The shared sequencers basically order transactions across rollups and commit them to the L1. Hence, by decentralising the shared sequencer set, you basically decentralise all the rollups linked to that sequencer set! To get a more detailed idea of the working of shared sequencers, you can also refer to this amazing article by Espresso.

Composability

One of the major issues of composability is understanding when the transaction is finalised on the other app chain and accordingly taking actions on your chain. But with shared sequencers, both the composable rollups share blocks with each other. So if a transaction rolls back on rollup B, the entire block is rolled back, and this causes the transaction on rollup A to revert as well.

Now this surely sounds easier said than done. For this. communication between rollups needs to be efficient and scalable. The shared sequencers need to come up with proper standards on how rollups can communicate, what should cross-chain messages look like, how to deal with rollup upgrades etc. While these are solvable problems, they are complicated and not easy to solve.

Developer experience

While the shared sequencers do abstract the decentralisation aspect and make cross-chain messaging easier, there are still some standards that every chain needs to follow to be compatible with the shared sequencer. For example, all rollup transaction needs to be transformed into a general format that the sequencer understands. Similarly, blocks from the sequencer need to be filtered to fetch the relevant transactions. To solve this, I would assume shared sequencers would come up with rollup frameworks or SDKs that abstract the boilerplate code and expose only the business logic part to app chain developers.

Here’s a diagram of how app chains will look with shared sequencers

Wait, it’s just Polkadot all over again

Polkadot started working on the multi-chain future much before Ethereum. In fact, they have been working on it for more than 5 years now and if you’re familiar with Polkadot, you might have noticed that the above design is basically re-inventing a lot of things Polkadot has already done!

The Relay Chain (Shared Decentralisation)

The Relay chain is basically the ordering engine + L1 in the sequence diagram above. The relay chain

  1. Orders transactions across all the parachains (rollups)
  2. It verifies the transactions executed correctly (instead of zk verification, it actually re-runs the execution code of the rollup to verify the state diffs)

You might have realised the relay is basically the shared sequencer we discussed above. Except for the fact that the relay chain also needs to do verify the execution (as Polkadot is an L1) whereas we leave that to Ethereum.

XCM and XCMP

We mentioned in the previous section that if every chain built its own methods to interoperate with other chains, we would soon be bloated with different standards and formats across all chains. You’ll need to keep track of all these formats for every chain you interact with. Moreover, you will also need to answer questions like what happens if a chain upgrades? However, these problems can be tackled elegantly by introducing standards that all chains must follow.

As you might have guessed, Polkadot has already done this. XCM is the messaging format and XCMP is the messaging protocol that all substrate chains can use to communicate with each other. I won’t go into the details of it but you can read about it here.

Substrate and Cumulus

Substrate is a framework developed by Parity that can be used to build blockchains. While all parachains on Polkadot use substrate, substrate is actually built in a chain-agnostic way. The framework abstracts all the common aspects of a blockchain so that you can just focus on your application logic. As we know, Madara is built on Substrate and so are Polkadot, Polygon Avail and many other projects. Moreover, Cumulus is a middleware on top of Substrate that allows you to connect your chain to Polkadot.

So continuing our analogy like before, Substrate and Cumulus can be thought of as substitutes to the rollup frameworks that allow you to build app chains and connect them to the shared sequencers.

Shared Sequencers → Relay Chains
Composability → XCM and XCMP
Rollup frameworks/Stacks → Substrate and Cumulus

So yes, it’s pretty much Polkadot all over again! Apart from this, Polkadot and Parity have some of the most experienced and funded teams that continue to build Substrate and Polkadot to add more features and make it more scalable. The technology is already battle-tested for years and has a ton of dev tooling out of the box.

Settle Polkadot on Ethereum?

While it’s true Polkadot did start building the multi-chain future way before Ethereum, there’s no denying that as of today, Ethereum is the most decentralised blockchain and the place where most of the apps and liquidity rests. However, what if there was a way to bring all the Polkadot tech into the Ethereum ecosystem?

There is! In fact, we have already started this with Madara. Madara uses the Substrate framework to allow anyone to build their own zk-powered L2/L3 solution on top of Ethereum. What we need next is the Polkadot relay chain in the form of a shared sequencer. So basically, if we can reuse the Polkadot relay chain but

  1. Remove the verification part as that happens on the L1 via zk proofs
  2. Commit the order of transactions to the L1
  3. Optimise the nodes and consensus algorithms to support Tendermint/HotStuff

We can get shared sequencers as mentioned before. Obviously, this is easier said than done. However, I believe this path is more pragmatic than rebuilding the sequencers, standards and frameworks from scratch. Polkadot has already solved a lot of problems in a chain-agnostic way which we can borrow for Ethereum. As a side product, we get

  1. An active set of developers that continue to build and educate the world about Substrate
  2. An active developer tooling set and a strong community
  3. A lot of active parachains can choose to settle on Ethereum as well if they wish to do so (we saw Astar do the same recently with the Polygon CDK)

Conclusion

My main idea behind writing this post is to open the discussion amongst the broader ecosystem of Starknet and Ethereum. I feel the shared sequencing model will play an important role in the decentralisation of not only Starknet but also all the app chains that consider building on top of it. As long as we are confident about the app chain thesis and zk scaling, a thorough analysis of the shared sequencing model is inevitable. Moreover, as Madara is moving towards production and Starknet has started its work on decentralisation, I feel this topic is now important to address. Hence, I request everyone reading this to leave any feedback/suggestions you have about the topic. Looking forward to reading your thoughts!

Appendix

Polkadot vs Cosmos

Cosmos, similar to Polkadot, has been solving for a multi-chain future for many years now. As a result, it has made a lot of developments with the Cosmos SDK and IBC and we also see a lot of app chains building on top of the Cosmos ecosystem. Hence, it’s only fair to consider Cosmos as well for this approach. My personal view on this topic is that Polkadot is more relevant as it solves the shared sequencers problem whereas Cosmos requires each app chain to build its own validator set. Moreover, Substrate has always been built in a chain-agnostic way to allow developers to build blockchains with no assumptions about consensus algorithms or the Polkadot ecosystem. This is also the reason why we chose Substrate for Madara. However, with that being said, my experience on Cosmos is limited and would love to hear more on this from the more experienced folks! You can also find more about the comparison of the two networks here.

It’s very interesting, I never thought about all that so first of all thank you for giving me the opportunity to think about it.

I don’t know much about Polkadot and Cosmos so I won’t be able to challenge your ideas. I like very much the global idea and I have a few questions that might hopefully clarify some details for me and others.

Concerning the shared sequencer, and because it will have to manage the txs coming from Starknet and Appchains, does this mean that the sequencer must be synchronized with all these blockchains to manage their states? And what about the size of all these elements? Won’t servers be limited by their hardware specifications (and so leading to a decentralization loss)?

Thanks @Bal7hazar for your response and feedback. I will try to answer your questions.

Concerning the shared sequencer, and because it will have to manage the transactions coming from Starknet and Appchains, does this mean that the sequencer must be synchronized with all these blockchains to manage their states?

So the shared sequencer is the blockchain which contains the blocks and the transactions of Starknet, Pragma, Kakarot and so on. The app chains technically then become execution engines. Instead of the sequencers syncing with the chains, it’s the other way round. The execution engines sync with the sequencers to know the latest blocks, execute the latest transactions and post the proofs on the L1.

So, if you need to build an app chain, you just build the execution logic and connect that with the shared sequencer set and you’re good to go (you might want to decentralise your execution set later on similar to PBS on Ethereum).

And what about the size of all these elements? Won’t servers be limited by their hardware specifications (and so leading to a decentralization loss)?

The sequencers don’t really contain the execution logic of any of the app chains. Instead, the sequencer defines a standard which allows any new chain to start posting transactions to it without any changes to the sequencer itself. As an example, the Polkadot relay chain (which actually does include the execution logic of the parachains) already has around 300 validators. If Starknet plans to go with Tendermint then this is already a very good number as Tendermint is known to support a smaller validator set. However, if we do need to support higher numbers, we can consider implementing algorithms like Hotstuff. Espresso has been researching along these lines.

That’s very clear thank you!

Great write-up, thanks for kickstarting this debate!

I think an important question this raises is the role of Starknet in the eventuality that 100 app chains are built on top of it. Should we then still use Starknet for regular individual activity or should Starknet itself act as a shared sequencer on which all apps settle?

Don’t get me wrong, we shouldn’t build for this right now, the priority should remain bringing genuine user activity on Starknet for the next 2-3 years, but today an increasing amount of activity on Ethereum is brought by L2 settlement. Starknet is in the top 10 gas guzzlers as we speak!

We should look closely as to how Ethereum is evolving and draw lessons for the future of Starknet. If Starknet becomes the settlement layer for 100’s of L3’s, I think it will de facto become the “shared sequencer” that you’re describing.

That’s indeed an interesting thought @NathanVDH. I will try to give my views on those points

the priority should remain bringing genuine user activity on Starknet for the next 2-3 years

I do agree with bringing more activity to Starknet for sure. Starknet is still early and we need a lot more good projects that bring more users and liquidity to the platform. However, there are already some apps that don’t want to be affected by block times, congestion and other factors of Starknet. Hence, we are already seeing projects like Pragma, Dojo, Mangata etc. building their own app chains. We should also see many go into production early next year and then each of them would try to solve for decentralisation in its own way. This would indeed be redundant and I feel it makes sense to have a single set of nodes that offer decentralisation as a service to all these chains (with the added benefit of interoperability).

If Starknet becomes the settlement layer for 100’s of L3’s, I think it will de facto become the “shared sequencer” that you’re describing.

Now that surely is one possibility. However, I would like to point out that shared sequencing by design happens at the beginning of the transaction lifecycle. As such, we need it to be quick with short block times and fast consensus. If we rely on Starknet to sequence blocks for L3s, it will become difficult for the L3s to support shorter block times. Moreover, in the case where app chains want to be L2s themselves that can interoperate with Starknet, this won’t work.

This is my opinion on the points you mentioned but would love to hear more thoughts on this. Thanks for your elaborate comment!

Definitely agree with you on the apps that require faster infra than what Starknet already offers, and I think the Madara stack will offer them the infra they need for their project. What I’m interested in is whether these apps will actually need validator sets or if they can simply use ZK proofs to ensure everything has been processed correctly. These appchains might have different decentralization requirements and we shouldn’t push any system on them “by default”. But I agree that the shared sequencer you’re describing would definitely be needed by a part of these appchains, though I think that it makes more sense if its built by a for-profit company though.

I think we shouldn’t underestimate the complexity of creating, incentivizing, and maintaining validator sets. It’s really complex and has its own drawbacks. There are tradeoffs between each choices and that’s why I think that a for-profit company should offer an option for these shared sequencers rather than see it “enshrined” into Starknet.

What I’m interested in is whether these apps will actually need validator sets or if they can simply use ZK proofs to ensure everything has been processed correctly.

I don’t see it as a “validator sets OR ZK proofs”. App chains need both just like Starknet is proved on the L1 using ZK but also needs to be decentralised to ensure censorship resistance and liveliness.

These appchains might have different decentralization requirements and we shouldn’t push any system on them “by default”

100% agree. The shared sequencer design is basically a model which we expect a lot of chains would eventually need. But if an app chain has other preferences, they are always open to build their own validator sets. However, for the remaining, the shared sequencer set will actually be an advantage as they don’t need to worry about validators, bridges etc. and can just focus on their business logic.

I think that a for-profit company should offer an option for these shared sequencers

You surely need incentives to build great products. However, that does not mean the product itself cannot be a public good. I think Starknet is great example here.

rather than see it “enshrined” into Starknet

Yep, I don’t think it should be enshrined within Starknet.

Great write up. Especially noble of you to look at other ecosystems and appreciate the hard work they have done up to this point - we need more of that in these times. Polkadot and Cosmos are full of smart and capable people, and we should all be incredibly glad and thankful for their efforts. Let me be the first to say that.

Additionally though, we should also be careful to look at the challegnes both ecosystems have gone through, and look at what possible solutions they are currently looking at. Even tough the technical implementation of shared sequencers and chain of chains is great on both, there are reasons the growth on these chains has not come even close to Ethereum.

One example here is the idea of thinking of theme / industry specific chain of chains. As we think through the matters mentioned in the OP (for example ordering of transactions, decentralisation etc.) we can begin to notice that different types of L3s might have different views of these - yet over time we might start to see similarities as well.

These similarities could be seen as different categories of using blockspace. What I am thinking about here are things like Gaming, Defi etc.

This is what I am seeing in Cosmos currently. Projects are collaborating and integrating with eachother more tightly to create themed zones.

Maybe Starknet app chains also should work towards this - A Gaming Zone, Defi Zone, RWA zone etc.

Thanks for that comment @Jommi. That’s actually a very interesting thought. I understand your point that we can maybe have zones for each category of apps - gaming, Defi, RWA and so on. And each of these zones would have something specific to offer for that zone which probably isn’t available in other zones. I am guessing you also imply that we have sets of shared sequencers, one set for each category (or maybe the same set of sequencers but different blocks for each category that follow different rules). However, I am curious to know your thoughts on what are those “X” factors that each category would need. Something that only makes sense to add to the Gaming zone, for example, and adding to all categories would hamper performance.

The thinking here is similar to sharding from the Near/Eth Roadmap, or local fee markets from Solana - so the reasoning would be similar. So just blockspace itself, but also something like blocktime etc.

Thanks for the writeup @apoorvsadana.

How clean is the separation of logic between the order engine and the rollup engine, actually? For example, if the order engine/shared sequencer just orders transactions from rollup_x which conform to a generic format then how does the it avoid getting DOSed through spam attack? How are txs which don’t pass validation rules which require rollup state to evaluate going to get filtered? One example is txs from accounts which can not fund gas.

Thinking about the composability feature across rollups/app chains provided by the Shared Sequencer, it seems the composability comes from the commitment to the order of transactions across the rollups. However, that commitment doesn’t protect against that chain stalling after the step of getting a tx order from the shared sequencer but before the txs are used to compute, prove, and verify the next state. So it seems the composability is a bit weaker than what you would find within Starknet or within Ethereum proper. It might be worth exploring what this shortcoming and potential others mean for the composability value proposition of a shared sequencer.

Maybe others have written about these questions. Thanks again for the brining this up.

Interesting. Maybe we can have some sorts of sharding or localization to allow for more control and prevent the noisy neighbour problem. Although, it’s important to mention that shared sequencer ONLY order transactions and do not execute them. So there’s already very little control that they have.

Thanks for the feedback @punk5736

The order engine does indeed only order transactions. The way to prevent DOS is using a fee token - the same way you would prevent DOS if you decentralised it on your own. This however does not mean that the rollup cannot have its own fee token. The rollup can choose to pay for the shared sequencing fees itself and collect the rollup token from the user.

When the rollup executes the transactions, it filters out all invalid transactions. So the final state commitments on the layer 1 do not include these transactions. In the case of Optimistic rollups, it won’t be possible to create fraud proofs for these invalid transactions because they were indeed invalid. In the case of ZK rollups, it should be relatively cheap to create a proof of the transaction being invalid.

I am not sure if I understand your question regarding the chain stalling. I think what you’re trying to say is

If the shared sequencers commit to txn_a and txn_b from two rollups A and B to be included in the same block, then what happens if rollup A shuts down?

If this is indeed your question, then nothing would happen as long as rollup A is still down. However, at the same time, it will NOT be possible for the rollup A to keep processing transactions by ignoring txn_a. The ONLY way for rollup A to move forward would be to either process txn_a or prove that it’s invalid (in the case of ZKR, but a similar argument can be made for OR). Also, given rollup A was secure enough, the code should have been openly available for anyone else to execute the transactions and post the results to the L1. So technically, rollup A going down is more about the risk you take when you choose to compose with the rollup and this risk would always exist with or without shared sequencers. Shared sequencers can, however, guarantee that the rollup will be forced to include txn_a when it comes back live.

These ideas are really nice. I have the following questions about them:

  1. If Order Engine does not have execution capabilities, how can we be sure that the transactions packed by Order Engine do not exceed the block capacity limit of the Rollup? After all, we can only know how much gas each transaction consumes after it is actually executed.
  2. Would the consensus of Order Engine be “overloaded”? Since each Rollup has an independent ecosystem, does the consensus system of Order Engine (POS system) have enough financial guarantees? In Polkadot, the relay chain only validates, not orders, which means that the relay chain can only refuse service at most, and will not be involved in the parachain ecosystem.
  3. How does Order Engine order transactions? Because it does not have an execution layer, it may be unaware of the content of the transactions. Does it simply follow the first-come-first-served rule?

Hey @jerrybaoo, these are some nice questions. My views on them are

  1. While the shared sequencing layer will produce blocks very quickly and will try to pack as many transactions as possible within a block, it won’t be necessary for every block within the shared sequencing layer to also be a block within an app chain. Its possible that 1 block at the shared sequencing layer is equal to 2 blocks on the app chain. The only important part is for the transaction order to be maintained and that could happen across blocks. This will however enforce the complication that if the shared sequencing layer reverts 1 block, the 2 corresponding blocks on the app chain need to be reverted.
  2. The order engine would technically be overloaded for ordering of transactions but at the end the source of truth would be Ethereum. I would assume techniques to evolve where you can exit any commitments on the L1 if the shared sequencing layer behaves in a malicious way for your app chain. In Polkadot, the entire security of app chains comes from the relay chain, if they refuse to service your parachain then you aren’t that secure anymore.
  3. That’s upto the shared sequencing layer to decide but it would mostly follow a fee mechanism and there will be block builders who will extract MEV and submit blocks to the layer. It will be similar to the PBS design we see on Ethereum but this one would be cross chain as the blocks contain transactions across multiple chains.