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

Update fee calculation logic to accept price #672

Merged
merged 35 commits into from
Feb 22, 2024

Conversation

MitchTurner
Copy link
Member

@MitchTurner MitchTurner commented Feb 8, 2024

Closes: #666
Closes: #667 (comment)

Partially completes: #664

@MitchTurner MitchTurner marked this pull request as ready for review February 14, 2024 18:13
@MitchTurner MitchTurner requested a review from a team February 14, 2024 18:15
@@ -495,7 +507,11 @@ fn message_message_coin() {

let block_height = rng.gen();
let err = tx
.check(block_height, &ConsensusParameters::standard())
.check(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a thought.

Hmm, it is the third time when we have updated a lot of places because of the modified number of arguments for the check function=D

Maybe it makes sense to accumulate all arguments inside of one type like CheckArgs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thinking about this more. There are no impls of check and only 4 impls of check_without_signature. I'm not too worried about it. It would be a lot more work rn to create a new type--all the places we call those functions. And those places would still need to be changed in the future.

This also goes back to the work I did a while ago breaking down the params so functions only use what they need. As soon as we start grouping things together again it gets harder to uphold the Interface Segregation Principle.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm pretty ambivalent about this one. I agree that it's a smell if we keep changing the interface, but I don't know if it's worth the work changing now.

@@ -277,7 +277,6 @@ mod tests {

fn assert_id_common_attrs<Tx: Buildable>(tx: &Tx) {
use core::ops::Deref;
assert_id_ne(tx, |t| t.set_gas_price(t.gas_price().not()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, maybe we want to do the same for tips

Copy link
Member Author

@MitchTurner MitchTurner Feb 17, 2024

Choose a reason for hiding this comment

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

Yeah. I was planning on doing a followup PR for tips.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I meant that you don't need to remove and add this part in the other PR. You simply can rename functions and you already are testing it. In this case, you will not lose the code that worked before.

It's okay to update the business logic in the next PR, but here we are testing serialization and deserialization that are the same.

@@ -19,7 +19,6 @@ fn tx_with_signed_coin_snapshot() {
predicate: Empty::new(),
predicate_data: Empty::new(),
}))
.gas_price(1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you replace it with tip(1), you don't need to change the snapshots=)

Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea of this test to serialise all possible fields

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm. Looks like there still is a diff. I'm not sure what this assertion_line means.

fuel-tx/src/transaction/types/mint.rs Show resolved Hide resolved
fuel-vm/src/checked_transaction.rs Show resolved Hide resolved
@@ -841,7 +863,6 @@ mod tests {
// input
#[quickcheck]
fn min_fee_coin_input(
Copy link
Collaborator

Choose a reason for hiding this comment

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

The purpose of this test to test different gas_price as well, could you return it back, please?=)

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed it because it isn't used, since the gas_price isn't attached to the tx anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But this test is for testing how fee calculation works in general, not how it works within the transaction.

@@ -945,7 +964,6 @@ mod tests {
// input
#[quickcheck]
fn min_fee_message_input(
Copy link
Collaborator

Choose a reason for hiding this comment

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

The purpose of this test to test different gas_price as well, could you return it back, please?=)

@@ -20,27 +20,35 @@ where
Tx: IntoChecked,
{
/// Finalize the builder into a [`Checked<Tx>`] of the correct type
fn finalize_checked(&mut self, height: BlockHeight) -> Checked<Tx>;
fn finalize_checked(&mut self, height: BlockHeight, gas_price: u64) -> Checked<Tx>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems gas_price can be part of the builder as well along with block_height

Copy link
Member Author

Choose a reason for hiding this comment

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

gas_price isn't part of the transaction, though. It's part of the block.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's true, but this type is used only in tests, and for simplicity it could be better=) But it is up to you since you need to update all palces in the fuel-core=)

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I prefer it this way. I'll just have to deal with any costs on the fuel-core side :)

pub(crate) fn run(&mut self) -> Result<ProgramState, InterpreterError<S::DataError>> {
pub(crate) fn run(
&mut self,
gas_price: Word,
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems can be part of the InterpreterParams along with another data=)

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess this is a question I had about this api in general. Will each instance of the interpreter only use a single price? Do we never share an interpreter between blocks? That's why I went this route.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We always create a new instance of the Interpreter for each transaction. We don't have plans to share interpreter, since it is faster to allocate a new memory for Interpreter instead of clearing manually the old one, based on our benchmarks=)

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay. I'm convinced that putting it on the Interpreter is a good idea, but I'm not going to put it on InterpreterParams because we have conversions from ConsensusParams that would need an additional parameter, if we just put it on Interpreter then we can keep those conversions.

I might rename InterpreterParams to InterpreterConsensusParams because that's a bit more accurate.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm. I'm having a similar problem with Interpreter. We have some From conversions for other types that don't have gas_price so I'm going have to replace a bunch of from methods with new functions.

It might end up being a better interface long term to have it held on the Interpreter, but it's not obvious to me right now if that's the right design.

I don't hate having the extra param on the execution methods for now.

Copy link
Member

@Voxelot Voxelot Feb 20, 2024

Choose a reason for hiding this comment

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

What about something like?

impl From<(ConsensusParameters, GasPrice)> for InterpreterParams {

Or maybe we just need to make a ::new constructor for InterpreterParams which accepts both ConsensusParams and GasPrice, instead of using a simple From conversion.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought about going with the tuple approach, but I don't feel like it is very idiomatic.

I'll give the constructor another shot.

@@ -692,6 +701,7 @@ where
pub fn deploy(
&mut self,
tx: Checked<Create>,
gas_price: Word,
Copy link
Collaborator

Choose a reason for hiding this comment

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

The same here, it can be part of the InterpreterParams

impl From<CheckPredicateParams> for InterpreterParams {
fn from(params: CheckPredicateParams) -> Self {
InterpreterParams {
// impl From<ConsensusParameters> for InterpreterParams {
Copy link
Member

Choose a reason for hiding this comment

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

Should we remove this commented out code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Gottit. Thanks.

@@ -1606,8 +1703,14 @@ mod tests {
where
Tx: Chargeable + field::Inputs + field::Outputs,
{
let available_balances =
balances::initial_free_balances(tx, gas_costs, fee_params, base_asset_id)?;
let arb_gas_price = 1;
Copy link
Member

Choose a reason for hiding this comment

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

Why did we stop using quickcheck to set the gas price?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh. I thought I fixed these spots. @xgreenx pointed it out but looks like I missed this one. Thanks.

fuel-vm/src/checked_transaction.rs Outdated Show resolved Hide resolved
fuel-vm/src/checked_transaction.rs Outdated Show resolved Hide resolved
@@ -217,7 +217,6 @@ fn transaction() {
vec![0xfa],
vec![0xfb, 0xfc],
Policies::new()
.with_gas_price(Word::MAX >> 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you also use tip here instead of the removing it, please?=) It is related to the encoding, so it is okay to keep

@MitchTurner MitchTurner added this pull request to the merge queue Feb 22, 2024
Merged via the queue into master with commit 77f44f8 Feb 22, 2024
37 checks passed
@MitchTurner MitchTurner deleted the use-gas-price-in-fee-calc branch February 22, 2024 01:02
@xgreenx xgreenx mentioned this pull request Feb 29, 2024
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.

Remove requirement to set gas price Update fee calculation logic to accept price
3 participants