Armani Ferrante 4 anni fa
parent
commit
17d62cbf30

+ 1 - 0
.travis.yml

@@ -40,6 +40,7 @@ jobs:
     - <<: *examples
       name: Runs the examples
       script:
+        - pushd examples/sysvars && anchor test && popd
         - pushd examples/tutorial/basic-0 && anchor test && popd
         - pushd examples/tutorial/basic-1 && anchor test && popd
         - pushd examples/tutorial/basic-2 && anchor test && popd

+ 5 - 5
cli/src/template.rs

@@ -4,7 +4,7 @@ use heck::SnakeCase;
 pub fn virtual_manifest() -> String {
     r#"[workspace]
 members = [
-  "programs/*"
+    "programs/*"
 ]
 "#
     .to_string()
@@ -47,10 +47,10 @@ use anchor::prelude::*;
 
 #[program]
 mod {} {{
-   use super::*;
-   pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {{
-       Ok(())
-   }}
+    use super::*;
+    pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {{
+        Ok(())
+    }}
 }}
 
 #[derive(Accounts)]

+ 2 - 0
examples/sysvars/Anchor.toml

@@ -0,0 +1,2 @@
+cluster = "localnet"
+wallet = "~/.config/solana/id.json"

+ 4 - 0
examples/sysvars/Cargo.toml

@@ -0,0 +1,4 @@
+[workspace]
+members = [
+    "programs/*"
+]

+ 15 - 0
examples/sysvars/programs/sysvars/Cargo.toml

@@ -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"] }

+ 2 - 0
examples/sysvars/programs/sysvars/Xargo.toml

@@ -0,0 +1,2 @@
+[target.bpfel-unknown-unknown.dependencies.std]
+features = []

+ 18 - 0
examples/sysvars/programs/sysvars/src/lib.rs

@@ -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,
+}

+ 19 - 0
examples/sysvars/tests/sysvars.js

@@ -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 - 0
src/lib.rs

@@ -127,4 +127,15 @@ pub mod prelude {
     pub use solana_sdk::entrypoint::ProgramResult;
     pub use solana_sdk::program_error::ProgramError;
     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;
 }

+ 36 - 1
syn/src/codegen/accounts.rs

@@ -1,6 +1,6 @@
 use crate::{
     AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
-    ConstraintSigner, Field, Ty,
+    ConstraintSigner, Field, SysvarTy, Ty,
 };
 use quote::quote;
 
@@ -45,6 +45,7 @@ pub fn generate(accs: AccountsStruct) -> proc_macro2::TokenStream {
             let info = match f.ty {
                 Ty::AccountInfo => quote! { #ident },
                 Ty::ProgramAccount(_) => quote! { #ident.info },
+                _ => return quote! {},
             };
             match f.is_mut {
                 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
         .constraints
@@ -150,6 +183,7 @@ pub fn generate_constraint_signer(f: &Field, _c: &ConstraintSigner) -> proc_macr
     let info = match f.ty {
         Ty::AccountInfo => quote! { #ident },
         Ty::ProgramAccount(_) => quote! { #ident.info },
+        _ => panic!("Invalid syntax: signer cannot be specified."),
     };
     quote! {
         if !#info.is_signer {
@@ -172,6 +206,7 @@ pub fn generate_constraint_owner(f: &Field, c: &ConstraintOwner) -> proc_macro2:
     let info = match f.ty {
         Ty::AccountInfo => quote! { #ident },
         Ty::ProgramAccount(_) => quote! { #ident.info },
+        _ => panic!("Invalid syntax: owner cannot be specified."),
     };
     match c {
         ConstraintOwner::Skip => quote! {},

+ 15 - 0
syn/src/lib.rs

@@ -72,6 +72,21 @@ pub struct Field {
 pub enum Ty {
     AccountInfo,
     ProgramAccount(ProgramAccountTy),
+    Sysvar(SysvarTy),
+}
+
+#[derive(PartialEq)]
+pub enum SysvarTy {
+    Clock,
+    Rent,
+    EpochSchedule,
+    Fees,
+    RecentBlockHashes,
+    SlotHashes,
+    SlotHistory,
+    StakeHistory,
+    Instructions,
+    Rewards,
 }
 
 #[derive(PartialEq)]

+ 11 - 1
syn/src/parser/accounts.rs

@@ -1,6 +1,6 @@
 use crate::{
     AccountsStruct, Constraint, ConstraintBelongsTo, ConstraintLiteral, ConstraintOwner,
-    ConstraintSigner, Field, ProgramAccountTy, Ty,
+    ConstraintSigner, Field, ProgramAccountTy, SysvarTy, Ty,
 };
 
 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() {
         "ProgramAccount" => Ty::ProgramAccount(parse_program_account(&path)),
         "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"),
     }
 }