Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

A way to enforce transaction order in a block #4177

Open
xlc opened this issue Nov 22, 2019 · 11 comments
Open

A way to enforce transaction order in a block #4177

xlc opened this issue Nov 22, 2019 · 11 comments
Labels
J0-enhancement An additional feature request.

Comments

@xlc
Copy link
Contributor

xlc commented Nov 22, 2019

Is it possible enforce certain transaction to be included in the beginning of the block? Or more generalized version, enforce transaction orders in a block.

A deterministic transaction order (e.g. order by their hash) reduces the ability for block author to manipulate the block in their favor. Block author won't be able to arbitrarily craft and insert transaction to gain advantages. They can still to do this in some degree but at least it will be harder.

Use case: I would like to enforce oracle transactions to always be included in the beginning of the block to reduce the possibility of front-running. By doing this, block producer will not able to craft and insert buy transaction before oracle price update and sell transaction after price update and making profit risk-free. With honest block producer that includes all received transactions, front runner will not able to monitor price change and make arbitrage because price update transaction is more likely to be executed before his arbitrage transaction.

@kianenigma
Copy link
Contributor

  • For the time being, you can do this with setting priority to high values. I am pretty sure the tx queue sorts transactions by priority so you have some sort of a control over it.

  • For the rest of it, I am not sure if we want to add a strict rule on the ordering of transactions on the block, but I am no expert in this aspect.

@bkchr
Copy link
Member

bkchr commented Nov 24, 2019

What you are describing sounds like a inherent? Why is the oracle transaction not an inherent?

@xlc
Copy link
Contributor Author

xlc commented Nov 24, 2019

@kianenigma

I don't think priority ordering is enforced by the consensus so it won't help the malicious validator case. It does step non validator front runners.

I don't see the downsides on strictly enforcing the transaction orders in a block by their priority?

@bkchr

Possibly. I haven't coded custom inherent myself so I have few questions about its usage.

  1. How does it differ to unsigned transaction created via offchain worker fundamentally?
  2. Can anyone craft and submit inherent transaction? I want to use membership and collective to manage who have permission to submit oracle transactions. https://github.com/laminar-protocol/flowchain/blob/65691cea364ce9305aa17dcee35e48c16956dec7/runtime/src/lib.rs#L299
  3. Does this means upgrade inherent creation logic needs validators to update their client software? (Which I think I can use IPC / RPC / config file to abstract the moving pieces)

@bkchr
Copy link
Member

bkchr commented Nov 25, 2019

Inherents are always created by the block author, so if you require that externals create these transactions, it does not work.

@burdges
Copy link

burdges commented Nov 25, 2019

We already do this for transactions that touch an account because account transactions have sequence numbers, right? A block producers can however omit an earlier transaction entirely, right?

@xlc
Copy link
Contributor Author

xlc commented Nov 25, 2019

Account sequence only enforce the transactions order signed by a same account. It does not prevent block producer change transaction order that created from different accounts.

Set oracle transactions with high priority can partially solve my problem. However I think currently it does not make block contain out or order transactions illegal, so it doesn't prevent malicious block author scenario.

@tomusdrw
Copy link
Contributor

@xlc If you emit an event during the dispatch, it should be later possible (for instance during block finalisation) to inspect that event and compare the extrinsic index it's placed on with the expected number of inherent extrinsics. So in such case if a block producer is not respecting the priority it would make the block invalid. Although seems more like a workaround than proper solution. We could provide some mechanism to simplify this.

@xlc
Copy link
Contributor Author

xlc commented Nov 26, 2019

@tomusdrw Thanks for the idea. A simplified approach will be just have the oracle update transaction itself check and validate its extrinsic index and panic if it is not in the right position.

@kianenigma kianenigma added the J0-enhancement An additional feature request. label Aug 18, 2020
@bkchr
Copy link
Member

bkchr commented Mar 23, 2023

This

A deterministic transaction order (e.g. order by their hash) reduces the ability for block author to manipulate the block in their favor.

Goes against this idea:

Use case: I would like to enforce oracle transactions to always be included in the beginning of the block to reduce the possibility of front-running.

In general the problem is that the client doesn't know what each transaction is. The only way would be that the runtime returns Priority::MAX for the oracle transaction when validating them. Then it would require some special logic that prevents other transactions to be included before the oracle transaction. But this sounds like some fragile system that will break very easily. The problem of solving front running is a problem on its own and pushing the oracle update as inherent is probably still the best idea.

@burdges
Copy link

burdges commented Mar 25, 2023

I doubt deterministic transaction order helps: You could typically craft transactions with extremely biased hashes, which slots them into the order where you like. Any unstaked funds could pass through intermediary accounts, for example. If you only do staked funds, then you still have issues like signatures' randomness, etc. You cannot even randomize the signature order by the block hash either, because collators originally ordered how they like.

Ask instead, what do you want from randomizing the order? If you're doing anything "real" then you'll typically want a steam lined chain without smart contracts, or with only limited functionality constracts. In these cases, you can often make transaction order irrelevant, like by fixing bid-ask spreads for the whole block. You cannot do this with fully smart contracts, but who cares? In other words, it's likely enough to solve the special cases that really matter, not solve all MEV.

@xlc
Copy link
Contributor Author

xlc commented Mar 26, 2023

This is not going to solve MEV but just makes it harder to do so which I think still nevertheless a good thing to have.

Yeah I agree the proper solution for the dex case is merge all the swap requests in a block so the order is completely irrelevant.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
J0-enhancement An additional feature request.
Projects
None yet
Development

No branches or pull requests

5 participants