Multiple bundles per block
This is the current approach, the operator will produce/submit multiple bundles to the consensus chain, and the consensus block may contain multiple bundles of a domain and derive a domain block.
We met several issues with this approach, while we have solution for each issue, they are still not perfectly fixed:
Duplicated transaction
A domain tx may be included in multiple bundles, all domain tx will be deduplicated before being put into the domain block, so the tx is only executed once and the user is only charged for the tx fee once but the tx is duplicated already store in the consensus block thus occupy more storage.
There are also several workaround/fix of this issue:
- Transaction range: the operator can only include tx that fall in their range into their bundle, the size of the tx-range is set to 1/3 and every operator will have their own random range, ideally when there is no overlay each operator bundle their own shard of tx pool
- The tx-range is probabilistic thus overlay is still possible and hence duplicated tx
- If a tx doesn’t fall into the tx-range it has to wait for the next bundle thus latency is increased
- Memorize produced bundle: the operator memorize the produced bundle, both bundle produced by itself or other operators (through bundle gossip in the domain network), and avoid including tx that was already included in the previous bundle again in their next bundle
- The bundle gossip also take time thus we can’t ensure the previous produced bundle can be noted by the operator before it producing it own bundle
- If the previous bundle wasn’t included in the consensus block due to some reasons (network delay/partition, the bundle is too big, etc) then the tx have to wait until next block thus increase latency
- Or even worse, if the tx depends on a tx included in the previous bundle (i.e. through nonce) the tx will be illegal and the bundle will be invalid without the previous bundle, thus the operator will be slashed
- Deduplication on the consensus side: the farmer deduplicates the domain tx in all bundles when constructing the block, so even the operator will submit bundle that contains duplicated tx this will ensure there will be no duplicated tx included in the consensus block
- While deduplication is easy for the farmer, it is hard for other farmers to verify if the deduplication is performed correctly, i.e. verifying every domain tx that committed to the bundle extrinsic root is still exist in the consensus block
Illegal transaction
If a bundle contains an illegal tx it will be consider as invalid and the producer will be slashed. While the domain block is derived from multiple bundles we can’t ensure the final domain block doesn’t contain illegal tx.
For example, the user can submit multiple tx with the same nonce but different contents, and all of them are included in different bundle. These tx is not duplicated tx but still only one of them will executed successfully and the other will be failed thus the user only pay for once while all tx will occupy storage.
Out of limit domain block size/weight
Currently, when the farmer validate bundle, it will check if the bundle’s size/weight exceeds the max domain block size/weight, and when constructing the consensus block, it will include as many bundle as possible (according to the consensus block size and the weight of the submit_bundle
). The will cause the final domain block exceed its size/weight limit, and once the limit is exceeded the following domain tx will be skip from execution thus causing a waste of storage.
There 2 approaches in general to fix the issue:
- The farmer check the bundle size/weight based on
max domain block size|weight / expected bundle number
, and remove the domain block size/weight limit during execution:- The expected bundle number is configurable through the slot probability which is probabilistic, thus the operator may produce more or less bundle but the right number of bundle on average.
- Add a check to the farmer when it constructing a block, to stop include more bundle for a domain once the limit is exceeded
One bundle per block
With this approach, the operator will produce/submit one bundle to the consensus chain, and the consensus block only includes at most one bundle for a specific domain, thus the domain block is derived from one bundle.
Because the bundle production is probabilistic, multiple bundles may be produced for the same domain block, in this case, the farmer only includes one bundle for a specific domain in the consensus block. The priority of the bundle may depend on their arrival order or their tip if we decide to split the domain tip to the farmer.
With this approach, the domain block is derived from one bundle and the producer can already perform comprehensive checks on the bundle to ensure the domain block won’t have any of the abovementioned issues:
- Duplicated transaction: the operator should deduplicate the tx within a bundle before submitting it to the consensus chain, otherwise the bundle will be considered invalid by the honest operator and cause the producer to be slashed
- Illegal transaction: similar to the duplicated tx, the operator needs to validate all tx of the bundle based on the latest domain state to ensure there is no illegal tx otherwise it will be slashed
- Out of limit domain block size/weight: since the domain block is derived from one bundle, the bundle size/weight limit represent the domain block size/weight the producer can easily ensure these limit. And exact size/weight limit can be configured by the domain creator based on their workload/usage of the domain.
One drawback of this approach found currently is that the bundle production frequency presents the frequency of picking domain tx to the consensus chain, if a domain tx is submitted after the bundle is produced and already submitted to the consensus block, this domain tx will have to wait until next block instead of the next bundle in the multiple bundles per block approach, which will be longer.