Sysvar support (#16)
This commit is contained in:
parent
cddc4f6bb6
commit
17d62cbf30
|
@ -40,6 +40,7 @@ jobs:
|
||||||
- <<: *examples
|
- <<: *examples
|
||||||
name: Runs the examples
|
name: Runs the examples
|
||||||
script:
|
script:
|
||||||
|
- pushd examples/sysvars && anchor test && popd
|
||||||
- pushd examples/tutorial/basic-0 && anchor test && popd
|
- pushd examples/tutorial/basic-0 && anchor test && popd
|
||||||
- pushd examples/tutorial/basic-1 && anchor test && popd
|
- pushd examples/tutorial/basic-1 && anchor test && popd
|
||||||
- pushd examples/tutorial/basic-2 && anchor test && popd
|
- pushd examples/tutorial/basic-2 && anchor test && popd
|
||||||
|
|
|
@ -4,7 +4,7 @@ use heck::SnakeCase;
|
||||||
pub fn virtual_manifest() -> String {
|
pub fn virtual_manifest() -> String {
|
||||||
r#"[workspace]
|
r#"[workspace]
|
||||||
members = [
|
members = [
|
||||||
"programs/*"
|
"programs/*"
|
||||||
]
|
]
|
||||||
"#
|
"#
|
||||||
.to_string()
|
.to_string()
|
||||||
|
@ -47,10 +47,10 @@ use anchor::prelude::*;
|
||||||
|
|
||||||
#[program]
|
#[program]
|
||||||
mod {} {{
|
mod {} {{
|
||||||
use super::*;
|
use super::*;
|
||||||
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {{
|
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {{
|
||||||
Ok(())
|
Ok(())
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#[derive(Accounts)]
|
#[derive(Accounts)]
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
cluster = "localnet"
|
||||||
|
wallet = "~/.config/solana/id.json"
|
|
@ -0,0 +1,4 @@
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"programs/*"
|
||||||
|
]
|
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "sysvars"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Created with Anchor"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
name = "sysvars"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
borsh = { git = "https://github.com/project-serum/borsh", branch = "serum", features = ["serum-program"] }
|
||||||
|
solana-program = "1.4.3"
|
||||||
|
solana-sdk = { version = "1.3.14", default-features = false, features = ["program"] }
|
||||||
|
anchor = { git = "https://github.com/project-serum/anchor", features = ["derive"] }
|
|
@ -0,0 +1,2 @@
|
||||||
|
[target.bpfel-unknown-unknown.dependencies.std]
|
||||||
|
features = []
|
|
@ -0,0 +1,18 @@
|
||||||
|
#![feature(proc_macro_hygiene)]
|
||||||
|
|
||||||
|
use anchor::prelude::*;
|
||||||
|
|
||||||
|
#[program]
|
||||||
|
mod sysvars {
|
||||||
|
use super::*;
|
||||||
|
pub fn sysvars(_ctx: Context<Sysvars>) -> ProgramResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Accounts)]
|
||||||
|
pub struct Sysvars {
|
||||||
|
pub clock: Clock,
|
||||||
|
pub rent: Rent,
|
||||||
|
pub stake_history: StakeHistory,
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
const anchor = require('@project-serum/anchor');
|
||||||
|
|
||||||
|
describe('sysvars', () => {
|
||||||
|
|
||||||
|
// Configure the client to use the local cluster.
|
||||||
|
anchor.setProvider(anchor.Provider.local());
|
||||||
|
|
||||||
|
it('Is initialized!', async () => {
|
||||||
|
const program = anchor.workspace.Sysvars;
|
||||||
|
const tx = await program.rpc.sysvars({
|
||||||
|
accounts: {
|
||||||
|
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
|
||||||
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||||
|
stakeHistory: anchor.web3.SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log("Your transaction signature", tx);
|
||||||
|
});
|
||||||
|
});
|
11
src/lib.rs
11
src/lib.rs
|
@ -127,4 +127,15 @@ pub mod prelude {
|
||||||
pub use solana_sdk::entrypoint::ProgramResult;
|
pub use solana_sdk::entrypoint::ProgramResult;
|
||||||
pub use solana_sdk::program_error::ProgramError;
|
pub use solana_sdk::program_error::ProgramError;
|
||||||
pub use solana_sdk::pubkey::Pubkey;
|
pub use solana_sdk::pubkey::Pubkey;
|
||||||
|
pub use solana_sdk::sysvar::clock::Clock;
|
||||||
|
pub use solana_sdk::sysvar::epoch_schedule::EpochSchedule;
|
||||||
|
pub use solana_sdk::sysvar::fees::Fees;
|
||||||
|
pub use solana_sdk::sysvar::instructions::Instructions;
|
||||||
|
pub use solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes;
|
||||||
|
pub use solana_sdk::sysvar::rent::Rent;
|
||||||
|
pub use solana_sdk::sysvar::rewards::Rewards;
|
||||||
|
pub use solana_sdk::sysvar::slot_hashes::SlotHashes;
|
||||||
|
pub use solana_sdk::sysvar::slot_history::SlotHistory;
|
||||||
|
pub use solana_sdk::sysvar::stake_history::StakeHistory;
|
||||||
|
pub use solana_sdk::sysvar::Sysvar;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
|
AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
|
||||||
ConstraintSigner, Field, Ty,
|
ConstraintSigner, Field, SysvarTy, Ty,
|
||||||
};
|
};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ pub fn generate(accs: AccountsStruct) -> proc_macro2::TokenStream {
|
||||||
let info = match f.ty {
|
let info = match f.ty {
|
||||||
Ty::AccountInfo => quote! { #ident },
|
Ty::AccountInfo => quote! { #ident },
|
||||||
Ty::ProgramAccount(_) => quote! { #ident.info },
|
Ty::ProgramAccount(_) => quote! { #ident.info },
|
||||||
|
_ => return quote! {},
|
||||||
};
|
};
|
||||||
match f.is_mut {
|
match f.is_mut {
|
||||||
false => quote! {},
|
false => quote! {},
|
||||||
|
@ -108,6 +109,38 @@ pub fn generate_field(f: &Field) -> proc_macro2::TokenStream {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ty::Sysvar(sysvar) => match sysvar {
|
||||||
|
SysvarTy::Clock => quote! {
|
||||||
|
let #ident = Clock::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::Rent => quote! {
|
||||||
|
let #ident = Rent::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::EpochSchedule => quote! {
|
||||||
|
let #ident = EpochSchedule::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::Fees => quote! {
|
||||||
|
let #ident = Fees::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::RecentBlockHashes => quote! {
|
||||||
|
let #ident = RecentBlockhashes::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::SlotHashes => quote! {
|
||||||
|
let #ident = SlotHashes::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::SlotHistory => quote! {
|
||||||
|
let #ident = SlotHistory::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::StakeHistory => quote! {
|
||||||
|
let #ident = StakeHistory::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::Instructions => quote! {
|
||||||
|
let #ident = Instructions::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
SysvarTy::Rewards => quote! {
|
||||||
|
let #ident = Rewards::from_account_info(#ident)?;
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let checks: Vec<proc_macro2::TokenStream> = f
|
let checks: Vec<proc_macro2::TokenStream> = f
|
||||||
.constraints
|
.constraints
|
||||||
|
@ -150,6 +183,7 @@ pub fn generate_constraint_signer(f: &Field, _c: &ConstraintSigner) -> proc_macr
|
||||||
let info = match f.ty {
|
let info = match f.ty {
|
||||||
Ty::AccountInfo => quote! { #ident },
|
Ty::AccountInfo => quote! { #ident },
|
||||||
Ty::ProgramAccount(_) => quote! { #ident.info },
|
Ty::ProgramAccount(_) => quote! { #ident.info },
|
||||||
|
_ => panic!("Invalid syntax: signer cannot be specified."),
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
if !#info.is_signer {
|
if !#info.is_signer {
|
||||||
|
@ -172,6 +206,7 @@ pub fn generate_constraint_owner(f: &Field, c: &ConstraintOwner) -> proc_macro2:
|
||||||
let info = match f.ty {
|
let info = match f.ty {
|
||||||
Ty::AccountInfo => quote! { #ident },
|
Ty::AccountInfo => quote! { #ident },
|
||||||
Ty::ProgramAccount(_) => quote! { #ident.info },
|
Ty::ProgramAccount(_) => quote! { #ident.info },
|
||||||
|
_ => panic!("Invalid syntax: owner cannot be specified."),
|
||||||
};
|
};
|
||||||
match c {
|
match c {
|
||||||
ConstraintOwner::Skip => quote! {},
|
ConstraintOwner::Skip => quote! {},
|
||||||
|
|
|
@ -72,6 +72,21 @@ pub struct Field {
|
||||||
pub enum Ty {
|
pub enum Ty {
|
||||||
AccountInfo,
|
AccountInfo,
|
||||||
ProgramAccount(ProgramAccountTy),
|
ProgramAccount(ProgramAccountTy),
|
||||||
|
Sysvar(SysvarTy),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum SysvarTy {
|
||||||
|
Clock,
|
||||||
|
Rent,
|
||||||
|
EpochSchedule,
|
||||||
|
Fees,
|
||||||
|
RecentBlockHashes,
|
||||||
|
SlotHashes,
|
||||||
|
SlotHistory,
|
||||||
|
StakeHistory,
|
||||||
|
Instructions,
|
||||||
|
Rewards,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
|
AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
|
||||||
ConstraintSigner, Field, ProgramAccountTy, Ty,
|
ConstraintSigner, Field, ProgramAccountTy, SysvarTy, Ty,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(strct: &syn::ItemStruct) -> AccountsStruct {
|
pub fn parse(strct: &syn::ItemStruct) -> AccountsStruct {
|
||||||
|
@ -69,6 +69,16 @@ fn parse_ty(f: &syn::Field) -> Ty {
|
||||||
match segments.ident.to_string().as_str() {
|
match segments.ident.to_string().as_str() {
|
||||||
"ProgramAccount" => Ty::ProgramAccount(parse_program_account(&path)),
|
"ProgramAccount" => Ty::ProgramAccount(parse_program_account(&path)),
|
||||||
"AccountInfo" => Ty::AccountInfo,
|
"AccountInfo" => Ty::AccountInfo,
|
||||||
|
"Clock" => Ty::Sysvar(SysvarTy::Clock),
|
||||||
|
"Rent" => Ty::Sysvar(SysvarTy::Rent),
|
||||||
|
"EpochSchedule" => Ty::Sysvar(SysvarTy::EpochSchedule),
|
||||||
|
"Fees" => Ty::Sysvar(SysvarTy::Fees),
|
||||||
|
"RecentBlockhashes" => Ty::Sysvar(SysvarTy::RecentBlockHashes),
|
||||||
|
"SlotHashes" => Ty::Sysvar(SysvarTy::SlotHashes),
|
||||||
|
"SlotHistory" => Ty::Sysvar(SysvarTy::SlotHistory),
|
||||||
|
"StakeHistory" => Ty::Sysvar(SysvarTy::StakeHistory),
|
||||||
|
"Instructions" => Ty::Sysvar(SysvarTy::Instructions),
|
||||||
|
"Rewards" => Ty::Sysvar(SysvarTy::Rewards),
|
||||||
_ => panic!("invalid type"),
|
_ => panic!("invalid type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue