Browse Source

lang: add sysvar custom error and failing test case (#1535)

Matthew Callens 3 years ago
parent
commit
a78c9c0341
5 changed files with 45 additions and 9 deletions
  1. 4 0
      CHANGELOG.md
  2. 7 4
      lang/src/accounts/sysvar.rs
  3. 3 0
      lang/src/error.rs
  4. 26 5
      tests/sysvars/tests/sysvars.js
  5. 5 0
      ts/src/error.ts

+ 4 - 0
CHANGELOG.md

@@ -11,6 +11,10 @@ incremented for features.
 
 ## [Unreleased]
 
+### Features
+
+* lang: Add new `AccountSysvarMismatch` error code and test cases for sysvars ([#1535](https://github.com/project-serum/anchor/pull/1535)).
+
 ## [0.22.1] - 2022-02-28
 
 ### Fixes

+ 7 - 4
lang/src/accounts/sysvar.rs

@@ -46,10 +46,13 @@ impl<'info, T: solana_program::sysvar::Sysvar + fmt::Debug> fmt::Debug for Sysva
 
 impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
     pub fn from_account_info(acc_info: &AccountInfo<'info>) -> Result<Sysvar<'info, T>> {
-        Ok(Sysvar {
-            info: acc_info.clone(),
-            account: T::from_account_info(acc_info)?,
-        })
+        match T::from_account_info(acc_info) {
+            Ok(val) => Ok(Sysvar {
+                info: acc_info.clone(),
+                account: val,
+            }),
+            Err(_) => Err(ErrorCode::AccountSysvarMismatch.into()),
+        }
     }
 }
 

+ 3 - 0
lang/src/error.rs

@@ -152,6 +152,9 @@ pub enum ErrorCode {
     /// 3014 - The given account is not the associated token account
     #[msg("The given account is not the associated token account")]
     AccountNotAssociatedTokenAccount,
+    /// 3015 - The given public key does not match the required sysvar
+    #[msg("The given public key does not match the required sysvar")]
+    AccountSysvarMismatch,
 
     // State.
     /// 4000 - The given state account does not have the correct address

+ 26 - 5
tests/sysvars/tests/sysvars.js

@@ -1,18 +1,39 @@
 const anchor = require("@project-serum/anchor");
+const assert = require("assert");
 
 describe("sysvars", () => {
   // Configure the client to use the local cluster.
   anchor.setProvider(anchor.Provider.local());
+  const program = anchor.workspace.Sysvars;
 
   it("Is initialized!", async () => {
-    const program = anchor.workspace.Sysvars;
-    const tx = await program.rpc.sysvars({
-      accounts: {
+    const tx = await program.methods
+      .sysvars()
+      .accounts({
         clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
         rent: anchor.web3.SYSVAR_RENT_PUBKEY,
         stakeHistory: anchor.web3.SYSVAR_STAKE_HISTORY_PUBKEY,
-      },
-    });
+      })
+      .rpc();
     console.log("Your transaction signature", tx);
   });
+
+  it("Fails when the wrote pubkeys are provided", async () => {
+    try {
+      await program.methods
+        .sysvars()
+        .accounts({
+          clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
+          rent: anchor.web3.SYSVAR_RENT_PUBKEY,
+          stakeHistory: anchor.web3.SYSVAR_REWARDS_PUBKEY,
+        })
+        .rpc();
+      assert.ok(false);
+    } catch (err) {
+      const errMsg = "The given public key does not match the required sysvar";
+      assert.strictEqual(err.toString(), errMsg);
+      assert.strictEqual(err.msg, errMsg);
+      assert.strictEqual(err.code, 3015);
+    }
+  });
 });

+ 5 - 0
ts/src/error.ts

@@ -111,6 +111,7 @@ const LangErrorCode = {
   AccountNotInitialized: 3012,
   AccountNotProgramData: 3013,
   AccountNotAssociatedTokenAccount: 3014,
+  AccountSysvarMismatch: 3015,
   // State.
   StateInvalidAddress: 4000,
 
@@ -227,6 +228,10 @@ const LangErrorMessage = new Map([
     LangErrorCode.AccountNotAssociatedTokenAccount,
     "The given account is not the associated token account",
   ],
+  [
+    LangErrorCode.AccountSysvarMismatch,
+    "The given public key does not match the required sysvar",
+  ],
 
   // State.
   [