-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
if you want to get some inspiration how to write a global variable in the runtime gav implemented one, it look like this: substrate/frame/support/src/traits.rs Lines 120 to 193 in 35f3ba4
Though you don't need to wrap in macro because you only need to have one in benchmarking. |
9d50761
to
0079140
Compare
Ideally, I wanted to make the whitelisting of calling account automatic. I wanted to extract the However, You can see my attempt here: 15ac408 It compiles and stuff, but you will notice I dont pass the Anyway, if @thiolliere you have an idea how to do this, all ears. Otherwise, this does do the functionality I want manually. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me, I like that whitelisted caller account is now more explicit
} { | ||
$( PRE { $( $pre_parsed:tt )* } )* | ||
} { $eval:block } { | ||
( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These macro changes are just superficial. I was trying to edit them at some point, and they were impossible to read to me. So I formatted them how I would expect to seem them. No logic actually changes in the macro parsing
/// Get the whitelist for tracking db reads/writes | ||
fn get_whitelist(&self) -> Vec<TrackedStorageKey> { | ||
Default::default() | ||
} | ||
|
||
/// Update the whitelist for tracking db reads/writes | ||
fn set_whitelist(&self, _: Vec<TrackedStorageKey>) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than have them unimplemented
I had them do nothing so they would work inside a test.
Otherwise, we would need to feature gate all get/set operations with #[cfg(not(test))]
@thiolliere @apopiak I think this PR is in a good spot for a review. I got all my desired features in there, so please take a look and ask any questions you might have. |
let has_been_read = KeyTracker { | ||
has_been_read: true, | ||
has_been_written: tracker.has_been_written, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic needed to be updated to support the scenario where we want to count a read, but ignore a write. (i.e. timestamp pallet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me, with not nitpicks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, some nits about naming
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
bot merge |
Missing process info; check that the PR belongs to a project column. Merge can be attempted if:
|
bot merge |
Checks failed; merge aborted. |
bot merge |
Checks failed; merge aborted. |
bot merge force |
Trying merge. |
polkadot companion: paritytech/polkadot#1612
This PR introduces a new
get_whitelist
host function. In combination withset_whitelist
, we are able to create helper functionsadd_whitelist
andremove_whitelist
which can be called from a benchmark to dynamically introduce or remove items from the benchmarking whitelist.Additionally, this PR updates the format of the whitelist to use a new struct
TrackedStorageKey
:Which includes the storage key, and whether this storage key has been read from or written to. This allows us to whitelist a key for a read, write, or both.
Here are some explicit examples of how you would use this:
Ignore Read, Track Write
Let's say that you have some storage value that is read each block, so you are able to ignore reads to that variable introduced by an extrinsic, but you still want to track the first write. For example, the
LaunchPeriod
of the democracy module may be placed as a storage item, and everyon_initialize
, we check if the block would trigger a launch period (reading it every block), but if we had an extrinsic to update the launch period, we would still want to track writes to this value. To your benchmark you would add the following:Track Read, Ignore Write
In some more unique scenarios, you may want to track the first read of a storage item, but ignore any writes to it. For example the Timestamp pallet has the
DidUpdate
variable which is transient (created and destroyed within one block), but before we create the value, we make sure it doesn't already exist. Thisexist
lookup should be counted as a storage read, but us writing to the value should not be counted because it will be removed at the end of the block, ultimately not committing anything to the DB. You would represent this like so:Ignore Read and Write
Finally, the most common scenario is to simply ignore both reads and writes to a storage key. For example, use a unique caller account, and want to make sure that reads/writes to the
System.Account
of that caller are not accounted for as they are already included in the base weight of an extrinsic. For this, we can use a shorthand to construct theTrackedStorageKey
by simply converting withkey.into()
, like so:fixes #6802