Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: meta transactions #8257

Merged
merged 5 commits into from
Jan 9, 2023
Merged

doc: meta transactions #8257

merged 5 commits into from
Jan 9, 2023

Conversation

jakmeier
Copy link
Contributor

No description provided.

@jakmeier jakmeier requested a review from a team as a code owner December 20, 2022 20:28
@jakmeier
Copy link
Contributor Author

@jakmeier jakmeier changed the title doc: meta transactions gas and balance flow doc: meta transactions Dec 22, 2022
@jakmeier
Copy link
Contributor Author

@mm-near I completed the documentation to the best of my knowledge, now including also all the other bits, not just the gas accounting. Hopefully it helps with your review of #7497.

@fadeevab and @e-uleyskiy I created this nearcore documentation regarding meta transactions to help other nearcore developers understand how it works. If you have a moment to read through it, I'd appreciate your feedback. I also stole your diagram, I hope that's okay.
(We might merge it before you have a chance to look at it, your feedback is still welcome afterwards. We always try to merge documentation quickly and follow up with improvements in separate PRs.)

docs/architecture/how/meta-tx.md Outdated Show resolved Hide resolved
docs/architecture/how/meta-tx.md Outdated Show resolved Hide resolved
possible `SEND` costs is chosen. The `EXEC` cost is not burned, yet. But it
is implicitly part of the transaction cost. The third and last part of the
transaction cost is the gas attached to function calls. The attached gas is
also called prepaid gas. (Not to be confused with `total_prepaid_exec_fees`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so there are basically 3 fields?

  • burned_gas
  • total_prepaid_exec_fees (these will be "burned" immediately on the receiver shard)
  • prepaid_gas (gas that is remaining)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yes, you can think of them as these 3 logical fields in this context. But you don't find them stored exactly like that. And throughout the code, there are more fields and their names are somewhat inconsistent...

If you look at ActionResult, the actual gas fields stored are:

pub gas_burnt: Gas,
pub gas_burnt_for_function_call: Gas,
pub gas_used: Gas,

Here the gas_used is = burned_gas + total_prepaid_exec_fees + prepaid_gas(outgoing).

The values for total_prepaid_exec_fees and prepaid_gas are never stored explicitly on the receipt level. It's always implicitly defined by the list of actions.

prepaid_gas is only relevant for function calls and 0 everywhere else. Adding up the prepaid gas inn all function calls of the receipt will give you the total prepaid_gas.

Likewise, the total_prepaid_exec_fees is the sum of all execution fees for all actions. We don't have to store it explicitly, because we can recompute it if we know the list of actions, which is why I wrote it is "implicitly" part of the total cost.

gas_burnt_for_function_call is not relevant for this discussion, it is only tracked separately for the 30% smart contract reward that only applies to the fraction of the cost that was burned for the actual function call.

In ExecutionOutcome you only have one gas field:

pub gas_burnt: Gas,

Everything else is implicitly defined by looking at the outgoing receipts.

delegate action wrapping them.
2. The cost of sending the inner actions and the delegate action from the
relayer to Alice's shard will be burned immediately. The condition `relayer
== Alice` determines which action `SEND` cost is taken (`sir` or `not_sir`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity - would it ever happen that Relayer == Alice ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I cannot think of a real scenario where it makes sense. Maybe testing your own relayer? Other than that it seems rather pointless. (Btw, we have many costs around SIR / NOT_SIR that practically don't make sense^^)


Each of these steps should make sense and not be too surprising. But the
consequence is that the implicit costs paid at the relayer's shard are
`SEND(1)` + `SEND(2)` + `EXEC` for all inner actions plus `SEND(1)` + `EXEC` for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Send(1) and Send(2) ?
Does it mean that we pay Send(1) twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Send(1) and Send(2) ?

It's the send costs where sender and receiver are defined by either Relayer/Alice or Alice/Bob. I've just added some text above that properly defines SEND(1) and SEND(2).

Does it mean that we pay Send(1) twice?

No. SEND(1) + SEND(2) is paid for the inner actions. Send fees are paid twice for inner actions but with different SIR condition. This should be the surprising bit, that send fees are charged twice for inner actions. This makes action sinside meta transactions more expensive than in normal transactions.

Only SEND(1) is charged for the one outer delegate action, without the inner actions. This is the obvious way to do it, exactly like every other action is charge today.

EXEC costs are paid for all actions involved, at block height h+1 for the outer action and h+2 for the inner actions. Note that when I write "cost of the outer action", this is exclusive the cost for inner actions.

4. On Bob's shard, we execute all inner actions and burn their `EXEC` cost.

Each of these steps should make sense and not be too surprising. But the
consequence is that the implicit costs paid at the relayer's shard are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So all of these are paid on relayer shard ? (as in point 3 above you say that some of them happen on the Alice's shard)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relayer pays everything upfront when purchasing the required amount of gas. The required amount of gas is implicitly defined by all actions in the receipt and potentially inner actions if we have a delegate action inside.

The burning happens in multiple steps. Burning is not the same as paying. I think I worded it correctly already, please let me know i I mixed it up somewhere.

the delegate action. This might be surprising but hopefully with this
explanation it makes sense now!


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW - you might also want to mention the gas refunds -- that they should go back to the relayer, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. I've added a paragraph for this. (Yes they are all sent to the relayer)


## Balance refunds in meta transactions

Unlike gas refunds, the protocol sends balance refunds to the predecessor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Balance refunds happen only when receipt fails (or runs out of gas), right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@jakmeier jakmeier requested a review from mm-near January 2, 2023 18:22
@jakmeier
Copy link
Contributor Author

jakmeier commented Jan 2, 2023

Hey @mm-near I've tried to answer your in-code questions. I know this topic (gas in general) is way more complicated than it appears and meta transactions add a weird twist to it. I struggle to make it consumable for a general nearcore developer audience without prior knowledge on meta transactions and only basic understanding of how we charge gas for actions.

Please let me know whether my explanations here make sense to you now, or which sections need improvment. (If you don't understand it, then who will?) I can rephrase some sections that currently are hard to grasp, or add more context where necessary.

Uleyskiy._


The graphic shows an example use case for meta transactions. Alice owns an
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overview section is great - thanks !

@near-bulldozer near-bulldozer bot merged commit cf294c9 into near:master Jan 9, 2023
@jakmeier jakmeier deleted the doc-meta-txgas branch January 9, 2023 16:07
nikurt pushed a commit to nikurt/nearcore that referenced this pull request Jan 15, 2023
* doc: meta transactions gas and balance flow

* document everything else about meta txs

* address review comments

* expand slightly more on complicated gas flow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants