Set the feePayer as the one who pays for the creation of an account - Anchor Solana - 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>,
}

Related

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

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>.

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

Go, first class functions, and best practices

For the past few days, I've been at a road block with regards to the best way to approach the issue of first class functions (assigning a callable to some variable), and the best practices in terms of efficiency.
Let's say I am programming a Yugioh card game, and I want each individual card of type card to have at least these attributes:
type card struct {
name string
text string
}
I have been struggling with the idea on where (and how) to program each card's individual functionality. I am currently convinced that the best place for the first-class function is in type card struct and create the new attribute as a "callable" like I would in Python (Go playground link).
package main
import "fmt"
type card struct {
name string
text string
f interface{}
}
type monsterCard struct {
card
attack int
defense int
}
type buff func(target *monsterCard) // Could be defined in a second file
type swap func(target *monsterCard, value int) // ditto
var increaseAttack buff = func(target *monsterCard) { // ditto
target.attack += 100
}
var swichStats swap = func(target *monsterCard, value int) { // ditto
attack := target.attack
target.attack = value
target.defense = attack
}
func main() {
m1 := monsterCard{
card: card{
name: "Celtic Guardian",
f: increaseAttack,
},
attack: 1400,
defense: 1200,
}
m2 := monsterCard{
card: card{
name: "Dark Magician",
f: swichStats,
},
attack: 2500,
defense: 2100,
}
var monsters = [2]monsterCard{m1, m2}
for _, m := range monsters {
fmt.Println(m)
switch m.f.(type) {
case buff:
m.f.(buff)(&m)
case swap:
m.f.(swap)(&m, m.defense)
default:
fmt.Printf("%T", m.f)
}
fmt.Println(m)
}
}
I'm not very good with regards to efficient code, and I completely understand I might be optimizing early here; however, I will need to program hundreds of these cards, and if having these callables exist in global scope with a heavy reliance on type assertion make the program slow, then I'll be in trouble reorganizing the code.
Are there any glaring issues that you can see with my methodology? Am I going about first-class functions correctly, or is there some kind of glaring performance issues I can't see? Any and all help will be greatly appreciated!
You can use plain functions, and closures where needed:
type card struct {
name string
text string
fn func(*monsterCard)
}
type monsterCard struct {
card
attack int
defense int
}
func (mc *monsterCard) call() {
mc.fn(mc)
}
func increaseAttack(mc *monsterCard) {
mc.attack += 100
}
func switchStats(mc *monsterCard) {
mc.attack, mc.defense = mc.defense, mc.attack
}
func updateTextAndAttack(text string, attack int) func(mc *monsterCard) {
return func(mc *monsterCard) {
mc.text, mc.attack = text, attack
}
}
https://play.golang.com/p/v_RbObnu7sN
You can also use plain methods, and closures where needed:
type card struct {
name string
text string
}
type monsterCard struct {
card
attack int
defense int
}
func (mc *monsterCard) increaseAttack() {
mc.attack += 100
}
func (mc *monsterCard) switchStats() {
mc.attack, mc.defense = mc.defense, mc.attack
}
func (mc *monsterCard) updateTextAndAttack(text string, attack int) func() {
return func() {
mc.text, mc.attack = text, attack
}
}
https://play.golang.com/p/Eo1mm-seldA
Thank you to everyone who helped me through to this answer. It would appear that I'm still using my scripting language mindset to try and solve problems in a compiled language. Instead of trying to create interfaces that ultimately lead to harder to read code, I will need to be more strict in my custom type definitions and implement a different function type for each type of card effect. Such strict enforcement will also allow for cards with multiple effects to exist in the game.
package main
type card struct {
name string
text string
}
type monsterCard struct {
card
attack int
defense int
}
type buffEffect struct {
monsterCard
fn buff
}
type setValueEffect struct {
monsterCard
fn swap
}
type buff func(target *monsterCard)
type swap func(target *monsterCard, value int)
var increaseAttack buff = func(target *monsterCard) {
target.attack += 100
}
var setAttackValue swap = func(target *monsterCard, value int) {
target.attack = value
}
func main() {
m1 := buffEffect{
monsterCard: monsterCard{
card: card{
name: "Celtic Guardian",
},
attack: 1400,
defense: 1200,
},
fn: increaseAttack,
}
m2 := setValueEffect{
monsterCard: monsterCard{
card: card{
name: "Dark Magician",
},
attack: 2500,
defense: 2100,
},
fn: setAttackValue,
}
m1.fn(&m1.monsterCard)
m2.fn(&m2.monsterCard, 100)
}

Efficient way to implement Towers of Hanoi with steps returned as string

I'm comparing several algorithms in JS, Rust and Go. I implemented Towsers of Hanoi this way in Go:
func Hanoi() (hanoi func(n int, from, via, to string) string) {
var moves strings.Builder
var hanoiRe func(n int, from, via, to string)
hanoiRe = func(n int, from, via, to string) {
if n > 0 {
hanoiRe(n-1, from, to, via)
moves.WriteString(from)
moves.WriteString("->")
moves.WriteString(to)
moves.WriteString("\n")
hanoiRe(n-1, via, from, to)
}
}
hanoi = func(n int, from, via, to string) string {
hanoiRe(n, from, via, to)
return moves.String()
}
return
}
But this implementation is much slower than JS or Rust. So I think, this could be done faster. But how?
I already tried type hanoi struct{moves strings.Builder} with func (h *hanoi) ..., which is a bit slower. The way using a string and moves += ...is much slower.
EDIT:
My comparisons:
JS:
class HanoiJS {
constructor() {
this.moves = "";
}
hanoi(n, from, via, to) {
if (n > 0) {
this.hanoi(n - 1, from, to, via);
this.moves += from + "->" + to + "\n";
this.hanoi(n - 1, via, from, to);
}
return this.moves;
}
}
Rust:
pub struct Hanoi {
moves: String
}
impl Hanoi {
pub fn new() -> Hanoi {
Hanoi {
moves: String::new()
}
}
pub fn hanoi(&mut self, n: i32, from: &str, via: &str, to: &str) -> &str {
if n > 0 {
self.hanoi(n - 1, from, to, via);
self.moves.push_str(from);
self.moves.push_str("->");
self.moves.push_str(to);
self.moves.push_str("\n");
self.hanoi(n - 1, via, from, to);
}
return &self.moves;
}
}
Compared with n=20 and 5 times:

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