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

CostModel::estimate_cost #3986

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

apfitzge
Copy link

@apfitzge apfitzge commented Dec 6, 2024

Problem

  • Current interface for CostModel does not provide a way to get cost without first resolving ATLs
  • Resolving ATLs is expensive due to looking in accounts-table
  • We ideally want to perform prioritization and see if we want to keep a transaction in our working set before resolving ATLs

Summary of Changes

  • Refactoring of private CostModel functions to take instruction iterator or static meta
  • Add CostModel::estimate_cost

Fixes #

@apfitzge apfitzge self-assigned this Dec 6, 2024
@apfitzge apfitzge marked this pull request as ready for review December 6, 2024 19:46
///
/// This assumes ALL features are activated.
/// This is intended to be used as an estimate of cost ONLY for the purposes of
/// prioritization and packing.

Choose a reason for hiding this comment

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

estimate_cost() essentially does same thing as calculate_cost(), but with a better interface. Both provide estimated cost for packing, for that purpose, it doesn't need a fully sanitized transaction if num_write_locks is known. How about sunset calculate_cost()? Maybe first step: fn calculate_cost(tx, feature_set) -> u64 { Self::estimate_cost(tx, tx.program_iter(), feature_set) }?

Choose a reason for hiding this comment

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

ps. calculate_cost_for_executed_transaction() (is for block limits enforcing) doesn't need fully sanitized transaction either, if num_write_locks is known.

Then the entire cost_model can be solely depends on StaticMeta, then "estimated cost" can itself be part of StaticMeta! wdyt?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah could do it - I guess my concern was primarily right now the number of write locks is behind a feature-gate.
Because before feature is activated we count actual number of locks.
After we count requested write locks.
So we technically need to have a fully sanitized transaction (at least to point of ALT resolution and lock demotion - which are usually our last steps) until we clean up that feature.

So it felt like a foot-gun to make that simple integer be an input for the "main" entrypoints.
I think once that feature is activated its' probably fine?

Copy link
Author

Choose a reason for hiding this comment

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

I reworked it so that all 3 main functions: calculate_cost, calculate_cost_for_executed_transaction, estimate_cost all have a shared implementation called for the non-vote transactions.


lazy_static! {
static ref ALL_FEATURES: FeatureSet = FeatureSet::all_enabled();
};

Choose a reason for hiding this comment

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

As suggested above, can let call side decided what feature_set to use.

Copy link
Author

Choose a reason for hiding this comment

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


TransactionCost::Transaction(usage_cost_details)
}
let num_write_locks = Self::num_write_locks(transaction, feature_set);

Choose a reason for hiding this comment

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

Don't have to gather write locks if it's simple-vote. Could make all three public functions (calculate_cost, calculate_cost_for_executed_transaction, estimate_cost) have same

if transaction.is_simple_vote_transaction() {
    return TransactionCost::SimpleVote { transaction };
}
// gather necessry stuff: num_write_locks, get_transaction_cost etc
Self::calculate_non_vote_transaction_cost(...)
}

fn calculate_non_vote_transaction_cost<'a, Tx: StaticMeta>(
transaction: &'a Tx,
instructions: impl Iterator<Item = (&'a Pubkey, SVMInstruction<'a>)> + Clone,
num_write_locks: u64,

Choose a reason for hiding this comment

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

nit: this parameter stands out as 'count' while the rest of parameters are 'cost'. Maybe change it to `cost' as well?

Copy link

@tao-stones tao-stones left a comment

Choose a reason for hiding this comment

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

lgtm

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.

2 participants