the trait `parity_scale_codec::Encode` is not implemented for `std::collections::BTreeMap<u128, T>` - substrate

Here is my struct:
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct SortitionSumTree<AccountId> {
pub k: u128,
pub stack: Vec<u128>,
pub nodes: Vec<u128>,
pub ids_to_tree_indexes: BTreeMap<AccountId, u128>,
pub node_indexes_to_ids: BTreeMap<u128, AccountId>,
}
My storage:
#[pallet::storage]
#[pallet::getter(fn sortition_sum_trees)]
pub type SortitionSumTrees<T> = StorageMap<_, Blake2_128Concat, Vec<u8>, SortitionSumTree<T>>;
But its giving error:
the trait parity_scale_codec::Encode is not implemented for std::collections::BTreeMap<u128, T>

You need to use this:
#[pallet::getter(fn sortition_sum_trees)]
pub type SortitionSumTrees<T> = StorageMap<
_,
Blake2_128Concat,
Vec<u8>,
SortitionSumTree<T::AccountId>
>;
Make sure to use T::AccountId in SortitionSumTree<T::AccountId>.

Related

Troubleshooting deepcopy-gen not generating deepcopy functions for custom Kubernetes API server

I am trying to create a custom kubernetes api server, and I have defined the types.go file in the directory pkg/apis/baz/v1alpha1,
package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Foo struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FooSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
type FooSpec struct {
Bar []string `json:"bar" protobuf:"bytes,1,rep,name=bar"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FooList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []Foo `json:"items" protobuf:"bytes,2,rep,name=items`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Bar struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Spec BarSpec
}
type BarSpec struct {
Description string `json:"description" protobuf:"bytes,1,opt,name=description"`
}
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type BarList struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []Bar `json:"items" protobuf:"bytes,2,rep,name=items"`
}
I have another types.go file which is for internal types, in the location pkg/apis/baz,
package baz
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Foo struct {
metav1.TypeMeta
metav1.ObjectMeta
Spec FooSpec
}
type FooSpec struct {
Bar []FooBar
}
type FooBar struct {
Name string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FooList struct {
metav1.TypeMeta
metav1.ListMeta
Items []Foo
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Bar struct {
metav1.TypeMeta
metav1.ObjectMeta
Spec BarSpec
}
type BarSpec struct {
// cost is the cost of one instance of this topping.
Description string
}
I am trying to generate the deepcopy functions for these using deepcopy-gen, I tried running the following command in the directory where deepcopy-gen is located,
./deepcopy-gen --input-dirs "$(PROJECT_ROOT)/pkg/apis/baz/v1alpha1" -O zz_generated.deepcopy
and the same for the internal types with a different location.
It doesn't seem to be working, no zz_generated.deepcopy file seems to be created after i run this command. It does not show any error, but the deepcopy functions file is not generated. What am I doing wrong?

Instantiate generic interface with any, struct doesn't implement it

Can someone explain, why *DataTo does not satisfy ToType[any]?
Trying to build a DTOer, that copies all values of one struct to another and also sets some explicit values (V in this case)
https://go.dev/play/p/-oobZrw5Ewe
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
type DataFrom struct {
V1 int
}
type DataTo struct {
V int
}
func (m *DataTo) SetVal() {
m.V = 1
return
}
type ToType[T any] interface {
SetVal()
*T
}
type DTO[TFrom any, TTo ToType[any]] struct {
Get func(from TFrom) TTo
}
func main() {
dto := &DTO[DataFrom, *DataTo]{
Get: func(from DataFrom) *DataTo {
return &DataTo{V: from.V1 + 666}
},
}
vFrom := DataFrom{V1: 1}
vTo := dto.Get(vFrom)
fmt.Println(vTo.V)
}
Because any is a static type.
If you use it to instantiate a generic type like ToType, that generic type will expect exactly any.
Now, certain usages of the type parameter might hide this issue, for example:
type Foo[T any] struct {
Value T
}
Foo[any]{Value: 12} // ok
Normally you are able to assign whatever type to any like the above, because any is just an alias of the empty interface interface{}, and any type satisfies the empty interface.
When the type parameter is used in composite types such as *T, then instantiating with any means exactly *any. Therefore you can imagine ToType[any] as the same thing as:
type ToTypeAny interface {
SetVal()
*any
}
And then *DataTo is obviously not *any. Further details: Assign struct pointer to interface pointer
If you declare the struct as follows it will compile:
type DTO[TFrom any, TTo ToType[DataTo]] struct {
Get func(from TFrom) TTo
}
Or in a more "generic" but also more verbose way:
type DTO[TFrom any, T any, TTo ToType[T]] struct {
Get func(from TFrom) TTo
}
&DTO[DataFrom, DataTo, *DataTo]{ ... }

Set the feePayer as the one who pays for the creation of an account - Anchor Solana

in any solana transaction there is a predefined feePayer who will pay for the transaction fee.
In my mind, this feePayer, would pay also for the creation of an account, instead, if not specified, in the same transaction, you can have a wallet that pays for the transaction fee and a wallet that pays for the creation of an account.
I have the following code:
#[program]
pub mod solana_twitter {
use super::*;
pub fn send_tweet(ctx: Context<SendTweet>, topic: String, content: String) -> ProgramResult {
let tweet: &mut Account<Tweet> = &mut ctx.accounts.tweet;
let author: &Signer = &ctx.accounts.author;
let clock: Clock = Clock::get().unwrap();
if topic.chars().count() > 50 {
return Err(ErrorCode::TopicTooLong.into())
}
if content.chars().count() > 280 {
return Err(ErrorCode::ContentTooLong.into())
}
tweet.author = *author.key;
tweet.timestamp = clock.unix_timestamp;
tweet.topic = topic;
tweet.content = content;
Ok(())
}
...
}
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = author, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account(mut)]
pub author: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
#[account]
pub struct Tweet {
pub author: Pubkey,
pub timestamp: i64,
pub topic: String,
pub content: String,
}
When I call the function SendTweet a Tweet account is created and the author of the tweet pays both for the transaction fee and the transfer of lamports for the rent exempt account creation (that is the tweet itself).
Now, in my front end code, to generate the transaction I added a new wallet and set it as feePayer.
In this case, everything works, but the feePayer only pay the transaction fee and the author pay for the account creation.
How can I set the feePayer also as the ones that pays for creating the account, leaving the first wallet as the author of the tweet?
I tried the following
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = fee_payer, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account()]
pub author: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
But it just says to me that does not found the fee_payer in the scope.
You're very close! In the first part, you have the author specified as the payer:
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = author, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account(mut)]
pub author: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
And in the second, you try to specify a separate payer:
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = fee_payer, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account()]
pub author: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
However, you've specified fee_payer instead of payer, which is the wrong variable name, so you just need to change this to:
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = fee_payer, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account()]
pub author: Signer<'info>,
#[account(mut)]
pub fee_payer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}

How to use a method as a function pointer in Rust

I have a trait method that needs to mutate internal data of a struct and I was hoping I could pass a setter method as a parameter to the trait method. I want to do this so that I can be flexible with what gets mutated by specifying the function passed as a parameter.
This code is a simplification of what I am trying to do, it has the same compiler issue.
Thanks
Code
struct MyStruct {
i: usize
}
impl MyStruct {
fn set_i(mut self, i: usize) -> Self {
self.i = i;
self
}
fn new() -> Self{
MyStruct{ i: 0 }
}
}
trait MyTrait {
fn do_some_setting(&mut self, setter_function: fn(&mut Self, usize) -> Self ) {
setter_function(&mut self, 7);
}
}
impl MyTrait for MyStruct {}
fn main() {
let mut s = MyStruct::new()
.set_i(3);
assert_eq!(s.i, 3);
s.do_some_setting(MyStruct::set_i);
assert_eq!(s.i, 7);
}
Problem
error[E0308]: mismatched types
--> src/main.rs:27:23
|
27 | s.do_some_setting(MyStruct::set_i);
| ^^^^^^^^^^^^^^^ expected `&mut MyStruct`, found struct `MyStruct`
|
= note: expected fn pointer `for<'r> fn(&'r mut MyStruct, _) -> MyStruct`
found fn item `fn(MyStruct, _) -> MyStruct {MyStruct::set_i}`
This does not work because MyTrait::do_some_setting expects a function whose first parameter is of type &mut Self whereas the first parameter of MyStruct::set_i is of type mut self.
You can fix this by changing the signature of MyStruct::set_i to set_i(&mut self, i: usize) but then the compiler would complain about mismatched types as it expects MyStruct::set_i to return Self but you'd be returning &mut Self. You can either derive Clone and return the struct after cloning it, or you can change the return type in the signature to &mut Self.
The compiler will once again complain about mismatched types as setter_function in MyTrait::do_some_setting is a function that returns Self, not &mut Self. You'll have to change the signature of setter_function to return &mut Self.
The compiler will now complain that temporary value dropped while borrowed at let mut s = MyStruct::new().set_i(3). You'll have to create MyStruct first and then use set_i on it.
At last, you'll end up with code that looks as follows:
struct MyStruct {
i: usize,
}
impl MyStruct {
fn set_i(&mut self, i: usize) -> &mut Self {
self.i = i;
self
}
fn new() -> Self {
MyStruct { i: 0 }
}
}
trait MyTrait {
fn do_some_setting(&mut self, setter_function: fn(&mut Self, usize) -> &mut Self) {
setter_function(self, 7);
}
}
impl MyTrait for MyStruct {}
fn main() {
let mut s = MyStruct::new();
s.set_i(3);
assert_eq!(s.i, 3);
s.do_some_setting(MyStruct::set_i);
assert_eq!(s.i, 7);
}
Playground Link

Define string output for type in Golang

I'm wondering if there's a way through fmt to specify the way a string would get outputted for specific types. For example, I have a token struct that contains a bunch of information on the token, like token type (which is an int, but for clarity reasons, it would make more sense if I could output the name of the token type as a string).
So when I print a specific type of variable, is there a straightforward way to specify/implement the string output of such a type?
If that doesn't really make sense, Rust has an excellent form of doing so (from their doc)
use std::fmt;
struct Point {
x: i32,
y: i32,
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
let origin = Point { x: 0, y: 0 };
println!("The origin is: {}", origin); // prints "The origin is: (0, 0)"
You need to implement the interface Stringer, like this:
import "fmt"
type Point struct {
x int
y int
}
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func main() {
fmt.Println(Point{1, 2})
}
(Go Playground)
In Go you don't specify which interfaces a type implements, you just implements the required methods.

Resources