-
Notifications
You must be signed in to change notification settings - Fork 683
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
Vision: Improve Usage of Constants in Pallets #303
Comments
The hard part of this exercise is to properly identify which Unfortunately we cannot migrate everything which SHOULD be a |
Hi @shawntabrizi can i take on this issue |
@Doordashcon Yes, please go ahead! If you need any help, please ping me or Shawn in the Substrate Technical channel on Element/Discord. |
@KiChjang sure thing |
@KiChjang want to submit task by task? |
I think the first two tasks can be done in 1 PR. Make sure your PR targets paritytech/substrate, not your fork |
is this the general idea for the second task? #[impl_const]
trait ConstantId {
const ID: i32;
} the attribute-like macro impl ConstGet<i32> for i32 {
fn get() -> i32
} |
@Doordashcon yes, but ideally within the trait itself?
Is that possible? |
I don't think the macro would know where it is called, so it cannot know about the ConstantId trait, which is a needed element for the expansion. Another approach would be to keep the attribute on the trait definition, but require a helper annotation on #[apply(derive_Gets!)]
trait ConstantId {
#[Get]
const ID: i32;
} And have the outer macro skip the associated items with no #[Get] applied to them. I would use a crate called |
This syntax: trait ConstantId {
#[impl_const_get]
const ID: i32;
} is actually doable in FRAME, assuming that |
The syntax trait ConstantId {
#[impl_const_get]
const ID: i32;
} would —within a sane implementation— be unable to generate an //! Expanded code
trait ConstantId {
const ID: i32;
impl … // Uh oh
} While there exists a contrived workaround to allow for such an //! Expansion: incorrect Rust
#[preprocessor_name] // <- actual proc-macro attribute <-------------------------------------------------+
trait ConstantId { // |
#[const_get] // <- fake proc-macro attr / inert attr that shall just act as a syntactical marker for --+
const ID: i32;
} It's way easier to implement (and the result is more readable). In fact, for a non-generic trait, with only associated constants, that shall be picked or ignored by the "preprocessor", then such a preprocessor can be implemented with a |
@danielhenrymantilla That is my point, we already have See the directory under |
We needed this feature in our pallet, the workaround we found is using traits, but is not optimal: trait ConstGet<T> {
const VALUE: T;
}
struct Two;
impl ConstGet<usize> for Two {
const VALUE: usize = 2;
}
struct Four;
impl ConstGet<usize> for Four {
const VALUE: usize = 4;
}
struct FixedArray<const N: usize>([u32; N]);
impl <const N: usize> FixedArray<N> {
fn new() -> Self {
Self([0;N])
}
}
type TwoByteArray = FixedArray::<{Two::VALUE}>;
type FourByteArray = FixedArray::<{Four::VALUE}>;
fn main() {
let a = TwoByteArray::new();
let b = FourByteArray::new();
println!("a: {:?}", a.0);
println!("b: {:?}", b.0);
} Then the Config definition is something like this: /// Configuration trait.
#[pallet::config]
pub trait Config: frame_system::Config {
...
// Constant array size
type ArraySize: ConstGet<usize>;
} |
Is there any more action on this? I noticed that paritytech/substrate#10287 was closed a year ago; I'd be interested in picking this up as it would be nice to have as a precursor for #290 (and #250). |
Hey @benluelo, you can pick this up :) |
I have a little bit of a grudge against this line of work as there is nothing at the language level that enforced Given this, I would just let go of this goal, instead of trying to give a pallet the false sense that something is constant (via Instead, I would focus on #244, which is about detection of |
At the moment, all configurations in the runtime use
trait Get<T>
in order to pass those configurations from the runtime definition to the pallet.However, many of these configurations are assumed to be constant, while others are not. At the Configuration API level, we provide no distinction for these differences, and thus are prone to errors caused by runtime misconfigurations.
To improve this, I propose the following changes:
ConstGet<T>
trait, with documentation that any use of this trait must be implemented by a true constant value.ConstGet<T>
so it can be used within the runtime for things like BoundedVecConstGet<T>
rather than justGet<T>
Get<T>
into const where it makes sense.ConstGet<T>
where it makes sense.paramter_types!
macro to generateConstGet<T>
onconst
, but not things likestatic
andstorage
The text was updated successfully, but these errors were encountered: