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

Improve gas checks in Randomness precompile #2051

Merged
merged 3 commits into from Jan 19, 2023

Conversation

nanocryk
Copy link
Contributor

@nanocryk nanocryk commented Jan 18, 2023

What does it do?

Improve gas checks in the precompile.

What important points reviewers should know?

Now the request gas_limit is how much gas will be available inside the the target rawFulfillRandomWords function, without any overhead costs. This simplifies the computations, and is backward compatible with current design (since it will be less that what it is required now).

The fulfiller however must now call the precompile with enough gas for the request gas_limit plus the overhead. They will be refunded the actually used amount, overhead included. They are also refunded the cost of the transaction itself.

Is there something left for follow-up PRs?

What alternative implementations were considered?

Are there relevant PRs or issues in other repositories (Substrate, Polkadot, Frontier, Cumulus)?

What value does it bring to the blockchain users?

@nanocryk nanocryk added A0-pleasereview Pull request needs code review. B7-runtimenoteworthy Changes should be noted in any runtime-upgrade release notes D5-nicetohaveaudit⚠️ PR contains trivial changes to logic that should be properly reviewed. not-breaking Does not need to be mentioned in breaking changes labels Jan 18, 2023
@librelois librelois added breaking Needs to be mentioned in breaking changes and removed not-breaking Does not need to be mentioned in breaking changes labels Jan 18, 2023
.checked_add(request_gas_limit_with_overhead)
.ok_or(revert("overflow when computed max amount of refunded gas"))?;

let total_refunded_gas: U256 = total_refunded_gas.into();
let (base_fee, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
Copy link
Contributor

Choose a reason for hiding this comment

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

in theory we should include the second parameter (it is the amount of weight for calling min_gas_price() itself). we currently use a value of 0 for this, though.

@notlesh
Copy link
Contributor

notlesh commented Jan 18, 2023

The fulfiller however must now call the precompile with enough gas for the request gas_limit plus the overhead. They will be refunded the actually used amount, overhead included.

Right, I think this is how it was supposed to work. I think the fulfiller should be refunded >= entire txn cost, probably slightly more so there is an incentive for doing it. I'm not sure the changes in this PR are sufficient to calculate exactly this amount.

One way to do that would be to benchmark a no-op fulfill request to get an idea of how much gas it costs.

Note: the idea is that fulfilling a request is free for the fulfiller if they call it correctly, right? In that case, the cost of the transaction itself should be refunded too, right?

Yeah, as above -- it should be at worst free for them to call.

@notlesh
Copy link
Contributor

notlesh commented Jan 18, 2023

Another thing to consider is the risk of submitting a fulfill request txn but being too late (that is, someone beat you to it). Then you will get no refund and you'll lose some money in fees. It's not easy to quantify this...

Copy link
Contributor

@notlesh notlesh left a comment

Choose a reason for hiding this comment

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

I think this is good, but there might be room for more discussion around the design.

One improvement overall would be to have some documentation somewhere that covers all the different overhead values that we calculate and how they relate to the overall txn cost, refunds, risk, etc.

Comment on lines +403 to +415
// Since we cannot compute `prepare_and_finish_fulfillment_cost` now (we don't
// know the number of words), we compute the cost for the maximum allowed number of
// words.
let max_prepare_and_finish_fulfillment_cost =
prepare_and_finish_fulfillment_gas_cost::<Runtime>(
<Runtime as pallet_randomness::Config>::MaxRandomWords::get(),
);

if handle.remaining_gas() < max_prepare_and_finish_fulfillment_cost {
return Err(revert(alloc::format!(
"provided gas must be at least {max_prepare_and_finish_fulfillment_cost}"
)));
}
Copy link
Contributor

@4meta5 4meta5 Jan 18, 2023

Choose a reason for hiding this comment

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

So now the fulfill_request caller must overestimate the gas_limit just in case request.num_words = MaxWords:::get()?

Will the UI automatically do this or do we need to document is it somewhere

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, it must overestimate because it can be this value.

If it is under it will revert, thus the gas estimator will increase the gas limit automatically.

Copy link
Contributor

@4meta5 4meta5 left a comment

Choose a reason for hiding this comment

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

Note: the idea is that fulfilling a request is free for the fulfiller if they call it correctly, right? In that case, the cost of the transaction itself should be refunded too, right?

That sounds right

@nanocryk nanocryk merged commit b133edf into master Jan 19, 2023
@nanocryk nanocryk deleted the jeremy-randomness-precompile-fix-gaslimit branch January 19, 2023 11:52
@notlesh notlesh added D1-audited👍 PR contains changes to fund-managing logic that has been properly reviewed and externally audited and removed D5-nicetohaveaudit⚠️ PR contains trivial changes to logic that should be properly reviewed. labels Apr 26, 2023
imstar15 pushed a commit to OAK-Foundation/moonbeam that referenced this pull request May 16, 2023
* fix gas checks + more tests

* fix clippy warning

* PR feedback + refund tx cost

Co-authored-by: librelois <c@elo.tf>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A0-pleasereview Pull request needs code review. B7-runtimenoteworthy Changes should be noted in any runtime-upgrade release notes breaking Needs to be mentioned in breaking changes D1-audited👍 PR contains changes to fund-managing logic that has been properly reviewed and externally audited
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants