瀏覽代碼

lang: remove the state and interface attributes (#2285)

Jean Marchand (Exotic Markets) 2 年之前
父節點
當前提交
38bbb21c33
共有 69 個文件被更改,包括 148 次插入3421 次删除
  1. 2 4
      .github/workflows/no-cashing-tests.yaml
  2. 2 4
      .github/workflows/tests.yaml
  3. 3 0
      CHANGELOG.md
  4. 0 25
      Cargo.lock
  5. 0 4
      Makefile
  6. 15 11
      client/example/src/main.rs
  7. 1 66
      client/src/lib.rs
  8. 1 1
      docs/programs/tic-tac-toe/programs/tic-tac-toe/Cargo.toml
  9. 56 22
      examples/tutorial/basic-4/programs/basic-4/src/lib.rs
  10. 29 19
      examples/tutorial/basic-4/tests/basic-4.js
  11. 0 4
      lang/Cargo.toml
  12. 0 23
      lang/attribute/interface/Cargo.toml
  13. 0 243
      lang/attribute/interface/src/lib.rs
  14. 0 22
      lang/attribute/state/Cargo.toml
  15. 0 92
      lang/attribute/state/src/lib.rs
  16. 0 149
      lang/src/accounts/cpi_state.rs
  17. 0 6
      lang/src/accounts/mod.rs
  18. 0 171
      lang/src/accounts/state.rs
  19. 0 82
      lang/src/context.rs
  20. 2 8
      lang/src/error.rs
  21. 3 20
      lang/src/lib.rs
  22. 0 34
      lang/syn/src/codegen/accounts/constraints.rs
  23. 0 24
      lang/syn/src/codegen/program/accounts.rs
  24. 1 45
      lang/syn/src/codegen/program/common.rs
  25. 0 81
      lang/syn/src/codegen/program/cpi.rs
  26. 2 110
      lang/syn/src/codegen/program/dispatch.rs
  27. 2 6
      lang/syn/src/codegen/program/entry.rs
  28. 1 549
      lang/syn/src/codegen/program/handlers.rs
  29. 0 123
      lang/syn/src/codegen/program/instruction.rs
  30. 1 135
      lang/syn/src/idl/file.rs
  31. 0 2
      lang/syn/src/idl/mod.rs
  32. 2 63
      lang/syn/src/lib.rs
  33. 0 19
      lang/syn/src/parser/accounts/constraints.rs
  34. 1 19
      lang/syn/src/parser/accounts/mod.rs
  35. 0 3
      lang/syn/src/parser/program/mod.rs
  36. 0 315
      lang/syn/src/parser/program/state.rs
  37. 0 12
      tests/interface/Anchor.toml
  38. 0 4
      tests/interface/Cargo.toml
  39. 0 19
      tests/interface/package.json
  40. 0 20
      tests/interface/programs/counter-auth/Cargo.toml
  41. 0 2
      tests/interface/programs/counter-auth/Xargo.toml
  42. 0 35
      tests/interface/programs/counter-auth/src/lib.rs
  43. 0 19
      tests/interface/programs/counter/Cargo.toml
  44. 0 2
      tests/interface/programs/counter/Xargo.toml
  45. 0 73
      tests/interface/programs/counter/src/lib.rs
  46. 0 46
      tests/interface/tests/interface.js
  47. 0 1
      tests/misc/Anchor.toml
  48. 0 1
      tests/misc/programs/misc-optional/Cargo.toml
  49. 0 20
      tests/misc/programs/misc-optional/src/context.rs
  50. 0 35
      tests/misc/programs/misc-optional/src/lib.rs
  51. 0 1
      tests/misc/programs/misc/Cargo.toml
  52. 0 14
      tests/misc/programs/misc/src/context.rs
  53. 0 30
      tests/misc/programs/misc/src/lib.rs
  54. 0 19
      tests/misc/programs/misc2/Cargo.toml
  55. 0 2
      tests/misc/programs/misc2/Xargo.toml
  56. 0 38
      tests/misc/programs/misc2/src/lib.rs
  57. 1 72
      tests/misc/tests/misc/misc.ts
  58. 1 1
      tests/zero-copy/programs/zero-cpi/src/lib.rs
  59. 0 10
      ts/packages/anchor/src/coder/borsh/index.ts
  60. 10 46
      ts/packages/anchor/src/coder/borsh/instruction.ts
  61. 0 39
      ts/packages/anchor/src/coder/borsh/state.ts
  62. 0 6
      ts/packages/anchor/src/coder/index.ts
  63. 0 3
      ts/packages/anchor/src/coder/system/index.ts
  64. 0 14
      ts/packages/anchor/src/coder/system/state.ts
  65. 4 10
      ts/packages/anchor/src/error.ts
  66. 0 6
      ts/packages/anchor/src/idl.ts
  67. 8 25
      ts/packages/anchor/src/program/index.ts
  68. 0 6
      ts/packages/anchor/src/program/namespace/index.ts
  69. 0 286
      ts/packages/anchor/src/program/namespace/state.ts

+ 2 - 4
.github/workflows/no-cashing-tests.yaml

@@ -251,10 +251,8 @@ jobs:
             path: spl/token-proxy
           - cmd: cd tests/multisig && anchor test --skip-lint
             path: tests/multisig
-          - cmd: cd tests/interface && anchor test --skip-lint
-            path: tests/interface
-          - cmd: cd tests/lockup && anchor test --skip-lint
-            path: tests/lockup
+          # - cmd: cd tests/lockup && anchor test --skip-lint
+          #   path: tests/lockup
           - cmd: cd tests/swap/deps/openbook-dex/dex && cargo build-bpf -- --locked && cd ../../../ && anchor test --skip-lint
             path: tests/swap
           - cmd: cd tests/escrow && anchor test --skip-lint && npx tsc --noEmit

+ 2 - 4
.github/workflows/tests.yaml

@@ -361,10 +361,8 @@ jobs:
             path: spl/token-proxy
           - cmd: cd tests/multisig && anchor test --skip-lint
             path: tests/multisig
-          - cmd: cd tests/interface && anchor test --skip-lint
-            path: tests/interface
-          - cmd: cd tests/lockup && anchor test --skip-lint
-            path: tests/lockup
+          # - cmd: cd tests/lockup && anchor test --skip-lint
+          #   path: tests/lockup
           - cmd: cd tests/swap/deps/openbook-dex/dex && cargo build-bpf -- --locked && cd ../../../ && anchor test --skip-lint
             path: tests/swap
           - cmd: cd tests/escrow && anchor test --skip-lint && npx tsc --noEmit

+ 3 - 0
CHANGELOG.md

@@ -11,12 +11,15 @@ The minor version will be incremented upon a breaking change and the patch versi
 ## [Unreleased]
 
 ### Features
+
 - cli: Add `env` option to verifiable builds ([#2325](https://github.com/coral-xyz/anchor/pull/2325)).
 
 ### Fixes
 
 ### Breaking
 
+- lang: Remove `state` and `interface` attributes ([#2285](https://github.com/coral-xyz/anchor/pull/2285)).
+
 ## [0.26.0] - 2022-12-15
 
 ### Features

+ 0 - 25
Cargo.lock

@@ -150,18 +150,6 @@ dependencies = [
  "syn 1.0.103",
 ]
 
-[[package]]
-name = "anchor-attribute-interface"
-version = "0.26.0"
-dependencies = [
- "anchor-syn",
- "anyhow",
- "heck 0.3.3",
- "proc-macro2 1.0.47",
- "quote 1.0.21",
- "syn 1.0.103",
-]
-
 [[package]]
 name = "anchor-attribute-program"
 version = "0.26.0"
@@ -173,17 +161,6 @@ dependencies = [
  "syn 1.0.103",
 ]
 
-[[package]]
-name = "anchor-attribute-state"
-version = "0.26.0"
-dependencies = [
- "anchor-syn",
- "anyhow",
- "proc-macro2 1.0.47",
- "quote 1.0.21",
- "syn 1.0.103",
-]
-
 [[package]]
 name = "anchor-cli"
 version = "0.26.0"
@@ -252,9 +229,7 @@ dependencies = [
  "anchor-attribute-constant",
  "anchor-attribute-error",
  "anchor-attribute-event",
- "anchor-attribute-interface",
  "anchor-attribute-program",
- "anchor-attribute-state",
  "anchor-derive-accounts",
  "arrayref",
  "base64 0.13.1",

+ 0 - 4
Makefile

@@ -23,12 +23,8 @@ publish:
 	sleep 25
 	cd lang/attribute/error/ && cargo publish && cd ../../../
 	sleep 25
-	cd lang/attribute/interface/ && cargo publish && cd ../../../
-	sleep 25
 	cd lang/attribute/program/ && cargo publish && cd ../../..
 	sleep 25
-	cd lang/attribute/state/ && cargo publish && cd ../../../
-	sleep 25
 	cd lang/attribute/event/ && cargo publish && cd ../../../
 	sleep 25
 	cd lang/ && cargo publish && cd ../

+ 15 - 11
client/example/src/main.rs

@@ -16,8 +16,8 @@ use optional::accounts::Initialize as OptionalInitialize;
 use optional::instruction as optional_instruction;
 // The `accounts` and `instructions` modules are generated by the framework.
 use basic_4::accounts as basic_4_accounts;
-use basic_4::basic_4::Counter as CounterState;
 use basic_4::instruction as basic_4_instruction;
+use basic_4::Counter as CounterAccount;
 use clap::Parser;
 // The `accounts` and `instructions` modules are generated by the framework.
 use composite::accounts::{Bar, CompositeUpdate, Foo, Initialize};
@@ -207,24 +207,28 @@ fn events(client: &Client, pid: Pubkey) -> Result<()> {
 pub fn basic_4(client: &Client, pid: Pubkey) -> Result<()> {
     let program = client.program(pid);
     let authority = program.payer();
+    let (counter, _) = Pubkey::find_program_address(&[b"counter"], &pid);
 
-    // Invoke the state's `new` constructor.
     program
-        .state_request()
-        .accounts(basic_4_accounts::Auth { authority })
-        .new(basic_4_instruction::state::New)
+        .request()
+        .accounts(basic_4_accounts::Initialize {
+            counter,
+            authority,
+            system_program: system_program::ID,
+        })
+        .args(basic_4_instruction::Initialize {})
         .send()?;
-    let counter_account: CounterState = program.state()?;
+    let counter_account: CounterAccount = program.account(counter)?;
     assert_eq!(counter_account.authority, authority);
     assert_eq!(counter_account.count, 0);
 
-    // Call a state method.
     program
-        .state_request()
-        .accounts(basic_4_accounts::Auth { authority })
-        .args(basic_4_instruction::state::Increment)
+        .request()
+        .accounts(basic_4_accounts::Increment { counter, authority })
+        .args(basic_4_instruction::Increment {})
         .send()?;
-    let counter_account: CounterState = program.state()?;
+
+    let counter_account: CounterAccount = program.account(counter)?;
     assert_eq!(counter_account.authority, authority);
     assert_eq!(counter_account.count, 1);
 

+ 1 - 66
client/src/lib.rs

@@ -5,7 +5,6 @@ use anchor_lang::solana_program::hash::Hash;
 use anchor_lang::solana_program::instruction::{AccountMeta, Instruction};
 use anchor_lang::solana_program::program_error::ProgramError;
 use anchor_lang::solana_program::pubkey::Pubkey;
-use anchor_lang::solana_program::system_program;
 use anchor_lang::{AccountDeserialize, Discriminator, InstructionData, ToAccountMetas};
 use regex::Regex;
 use solana_account_decoder::UiAccountEncoding;
@@ -112,18 +111,6 @@ impl Program {
             self.cfg.cluster.url(),
             self.cfg.payer.clone(),
             self.cfg.options,
-            RequestNamespace::Global,
-        )
-    }
-
-    /// Returns a request builder for program state.
-    pub fn state_request(&self) -> RequestBuilder {
-        RequestBuilder::from(
-            self.program_id,
-            self.cfg.cluster.url(),
-            self.cfg.payer.clone(),
-            self.cfg.options,
-            RequestNamespace::State { new: false },
         )
     }
 
@@ -176,10 +163,6 @@ impl Program {
         })
     }
 
-    pub fn state<T: AccountDeserialize>(&self) -> Result<T, ClientError> {
-        self.account(anchor_lang::__private::state::address(&self.program_id))
-    }
-
     pub fn rpc(&self) -> RpcClient {
         RpcClient::new_with_commitment(
             self.cfg.cluster.url().to_string(),
@@ -400,18 +383,6 @@ pub struct RequestBuilder<'a> {
     // Serialized instruction data for the target RPC.
     instruction_data: Option<Vec<u8>>,
     signers: Vec<&'a dyn Signer>,
-    // True if the user is sending a state instruction.
-    namespace: RequestNamespace,
-}
-
-#[derive(PartialEq, Eq)]
-pub enum RequestNamespace {
-    Global,
-    State {
-        // True if the request is to the state's new ctor.
-        new: bool,
-    },
-    Interface,
 }
 
 impl<'a> RequestBuilder<'a> {
@@ -420,7 +391,6 @@ impl<'a> RequestBuilder<'a> {
         cluster: &str,
         payer: Rc<dyn Signer>,
         options: Option<CommitmentConfig>,
-        namespace: RequestNamespace,
     ) -> Self {
         Self {
             program_id,
@@ -431,7 +401,6 @@ impl<'a> RequestBuilder<'a> {
             instructions: Vec::new(),
             instruction_data: None,
             signers: Vec::new(),
-            namespace,
         }
     }
 
@@ -478,16 +447,6 @@ impl<'a> RequestBuilder<'a> {
         self
     }
 
-    /// Invokes the `#[state]`'s `new` constructor.
-    #[allow(clippy::wrong_self_convention)]
-    #[must_use]
-    pub fn new(mut self, args: impl InstructionData) -> Self {
-        assert!(self.namespace == RequestNamespace::State { new: false });
-        self.namespace = RequestNamespace::State { new: true };
-        self.instruction_data = Some(args.data());
-        self
-    }
-
     #[must_use]
     pub fn signer(mut self, signer: &'a dyn Signer) -> Self {
         self.signers.push(signer);
@@ -495,36 +454,12 @@ impl<'a> RequestBuilder<'a> {
     }
 
     pub fn instructions(&self) -> Result<Vec<Instruction>, ClientError> {
-        let mut accounts = match self.namespace {
-            RequestNamespace::State { new } => match new {
-                false => vec![AccountMeta::new(
-                    anchor_lang::__private::state::address(&self.program_id),
-                    false,
-                )],
-                true => vec![
-                    AccountMeta::new_readonly(self.payer.pubkey(), true),
-                    AccountMeta::new(
-                        anchor_lang::__private::state::address(&self.program_id),
-                        false,
-                    ),
-                    AccountMeta::new_readonly(
-                        Pubkey::find_program_address(&[], &self.program_id).0,
-                        false,
-                    ),
-                    AccountMeta::new_readonly(system_program::ID, false),
-                    AccountMeta::new_readonly(self.program_id, false),
-                ],
-            },
-            _ => Vec::new(),
-        };
-        accounts.extend_from_slice(&self.accounts);
-
         let mut instructions = self.instructions.clone();
         if let Some(ix_data) = &self.instruction_data {
             instructions.push(Instruction {
                 program_id: self.program_id,
                 data: ix_data.clone(),
-                accounts,
+                accounts: self.accounts.clone(),
             });
         }
 

+ 1 - 1
docs/programs/tic-tac-toe/programs/tic-tac-toe/Cargo.toml

@@ -16,6 +16,6 @@ cpi = ["no-entrypoint"]
 default = []
 
 [dependencies]
-anchor-lang = "=0.24.1"
+anchor-lang = "=0.26.0"
 num-traits = "0.2"
 num-derive = "0.3"

+ 56 - 22
examples/tutorial/basic-4/programs/basic-4/src/lib.rs

@@ -1,5 +1,5 @@
-// #region code
 use anchor_lang::prelude::*;
+use std::ops::DerefMut;
 
 declare_id!("CwrqeMj2U8tFr1Rhkgwc84tpAsqbt9pTt2a4taoTADPr");
 
@@ -7,38 +7,72 @@ declare_id!("CwrqeMj2U8tFr1Rhkgwc84tpAsqbt9pTt2a4taoTADPr");
 pub mod basic_4 {
     use super::*;
 
-    #[state]
-    pub struct Counter {
-        pub authority: Pubkey,
-        pub count: u64,
+    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
+        let counter = ctx.accounts.counter.deref_mut();
+        let bump = *ctx.bumps.get("counter").ok_or(ErrorCode::CannotGetBump)?;
+
+        *counter = Counter {
+            authority: *ctx.accounts.authority.key,
+            count: 0,
+            bump,
+        };
+
+        Ok(())
     }
 
-    impl Counter {
-        pub fn new(ctx: Context<Auth>) -> anchor_lang::Result<Self> {
-            Ok(Self {
-                authority: *ctx.accounts.authority.key,
-                count: 0,
-            })
-        }
-
-        pub fn increment(&mut self, ctx: Context<Auth>) -> anchor_lang::Result<()> {
-            if &self.authority != ctx.accounts.authority.key {
-                return Err(error!(ErrorCode::Unauthorized));
-            }
-            self.count += 1;
-            Ok(())
-        }
+    pub fn increment(ctx: Context<Increment>) -> Result<()> {
+        require_keys_eq!(
+            ctx.accounts.authority.key(),
+            ctx.accounts.counter.authority,
+            ErrorCode::Unauthorized
+        );
+
+        ctx.accounts.counter.count += 1;
+        Ok(())
     }
 }
 
 #[derive(Accounts)]
-pub struct Auth<'info> {
+pub struct Initialize<'info> {
+    #[account(
+        init,
+        payer = authority,
+        space = Counter::SIZE,
+        seeds = [b"counter"],
+        bump
+    )]
+    counter: Account<'info, Counter>,
+    #[account(mut)]
     authority: Signer<'info>,
+    system_program: Program<'info, System>,
+}
+
+#[derive(Accounts)]
+pub struct Increment<'info> {
+    #[account(
+        mut,
+        seeds = [b"counter"],
+        bump = counter.bump
+    )]
+    counter: Account<'info, Counter>,
+    authority: Signer<'info>,
+}
+
+#[account]
+pub struct Counter {
+    pub authority: Pubkey,
+    pub count: u64,
+    pub bump: u8,
+}
+
+impl Counter {
+    pub const SIZE: usize = 8 + 32 + 8 + 1;
 }
-// #endregion code
 
 #[error_code]
 pub enum ErrorCode {
     #[msg("You are not authorized to perform this action.")]
     Unauthorized,
+    #[msg("Cannot get the bump.")]
+    CannotGetBump,
 }

+ 29 - 19
examples/tutorial/basic-4/tests/basic-4.js

@@ -7,35 +7,45 @@ describe("basic-4", () => {
   // Configure the client to use the local cluster.
   anchor.setProvider(provider);
 
-  const program = anchor.workspace.Basic4;
+  const program = anchor.workspace.Basic4,
+    counterSeed = anchor.utils.bytes.utf8.encode("counter");
+
+  let counterPubkey;
+
+  before(async () => {
+    [counterPubkey] = await anchor.web3.PublicKey.findProgramAddress(
+      [counterSeed],
+      program.programId
+    );
+  });
 
   it("Is runs the constructor", async () => {
-    // #region ctor
     // Initialize the program's state struct.
-    await program.state.rpc.new({
-      accounts: {
+    await program.methods
+      .initialize()
+      .accounts({
+        counter: counterPubkey,
         authority: provider.wallet.publicKey,
-      },
-    });
-    // #endregion ctor
+        systemProgram: anchor.web3.SystemProgram.programId,
+      })
+      .rpc();
 
     // Fetch the state struct from the network.
-    // #region accessor
-    const state = await program.state.fetch();
-    // #endregion accessor
+    const counterAccount = await program.account.counter.fetch(counterPubkey);
 
-    assert.ok(state.count.eq(new anchor.BN(0)));
+    assert.ok(counterAccount.count.eq(new anchor.BN(0)));
   });
 
   it("Executes a method on the program", async () => {
-    // #region instruction
-    await program.state.rpc.increment({
-      accounts: {
+    await program.methods
+      .increment()
+      .accounts({
+        counter: counterPubkey,
         authority: provider.wallet.publicKey,
-      },
-    });
-    // #endregion instruction
-    const state = await program.state.fetch();
-    assert.ok(state.count.eq(new anchor.BN(1)));
+      })
+      .rpc();
+
+    const counterAccount = await program.account.counter.fetch(counterPubkey);
+    assert.ok(counterAccount.count.eq(new anchor.BN(1)));
   });
 });

+ 0 - 4
lang/Cargo.toml

@@ -19,10 +19,8 @@ anchor-debug = [
     "anchor-attribute-constant/anchor-debug",
     "anchor-attribute-error/anchor-debug",
     "anchor-attribute-event/anchor-debug",
-    "anchor-attribute-interface/anchor-debug",
     "anchor-attribute-program/anchor-debug",
     "anchor-attribute-program/anchor-debug",
-    "anchor-attribute-state/anchor-debug",
     "anchor-derive-accounts/anchor-debug"
 ]
 
@@ -32,8 +30,6 @@ anchor-attribute-account = { path = "./attribute/account", version = "0.26.0" }
 anchor-attribute-constant = { path = "./attribute/constant", version = "0.26.0" }
 anchor-attribute-error = { path = "./attribute/error", version = "0.26.0" }
 anchor-attribute-program = { path = "./attribute/program", version = "0.26.0" }
-anchor-attribute-state = { path = "./attribute/state", version = "0.26.0" }
-anchor-attribute-interface = { path = "./attribute/interface", version = "0.26.0" }
 anchor-attribute-event = { path = "./attribute/event", version = "0.26.0" }
 anchor-derive-accounts = { path = "./derive/accounts", version = "0.26.0" }
 arrayref = "0.3.6"

+ 0 - 23
lang/attribute/interface/Cargo.toml

@@ -1,23 +0,0 @@
-[package]
-name = "anchor-attribute-interface"
-version = "0.26.0"
-authors = ["Serum Foundation <foundation@projectserum.com>"]
-repository = "https://github.com/coral-xyz/anchor"
-license = "Apache-2.0"
-description = "Attribute for defining a program interface trait"
-rust-version = "1.59"
-edition = "2021"
-
-[lib]
-proc-macro = true
-
-[features]
-anchor-debug = ["anchor-syn/anchor-debug"]
-
-[dependencies]
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0.60", features = ["full"] }
-anyhow = "1.0.32"
-anchor-syn = { path = "../../syn", version = "0.26.0" }
-heck = "0.3.2"

+ 0 - 243
lang/attribute/interface/src/lib.rs

@@ -1,243 +0,0 @@
-extern crate proc_macro;
-
-use anchor_syn::parser;
-use heck::SnakeCase;
-use quote::quote;
-use syn::parse_macro_input;
-
-/// The `#[interface]` attribute allows one to define an external program
-/// dependency, without having any knowledge about the program, other than
-/// the fact that it implements the given trait.
-///
-/// Additionally, the attribute generates a client that can be used to perform
-/// CPI to these external dependencies.
-///
-/// # Example
-///
-/// In the following example, we have a counter program, where the count
-/// can only be set if the configured external program authorizes it.
-///
-/// ## Defining an `#[interface]`
-///
-/// First we define the program that depends on an external interface.
-///
-/// ```ignore
-/// use anchor_lang::prelude::*;
-///
-/// #[interface]
-/// pub trait Auth<'info, T: Accounts<'info>> {
-///     fn is_authorized(ctx: Context<T>, current: u64, new: u64) -> anchor_lang::Result<()>;
-/// }
-///
-/// #[program]
-/// pub mod counter {
-///     use super::*;
-///
-///     #[state]
-///     pub struct Counter {
-///         pub count: u64,
-///         pub auth_program: Pubkey,
-///     }
-///
-///     impl Counter {
-///         pub fn new(_ctx: Context<Empty>, auth_program: Pubkey) -> Result<Self> {
-///             Ok(Self {
-///                 count: 0,
-///                 auth_program,
-///             })
-///         }
-///
-///         #[access_control(SetCount::accounts(&self, &ctx))]
-///         pub fn set_count(&mut self, ctx: Context<SetCount>, new_count: u64) -> Result<()> {
-///             // Ask the auth program if we should approve the transaction.
-///             let cpi_program = ctx.accounts.auth_program.clone();
-///             let cpi_ctx = CpiContext::new(cpi_program, Empty {});
-///
-///             // This is the client generated by the `#[interface]` attribute.
-///             auth::is_authorized(cpi_ctx, self.count, new_count)?;
-///
-///             // Approved, so update.
-///             self.count = new_count;
-///             Ok(())
-///         }
-///     }
-/// }
-///
-/// #[derive(Accounts)]
-/// pub struct Empty {}
-///
-/// #[derive(Accounts)]
-/// pub struct SetCount<'info> {
-///     auth_program: AccountInfo<'info>,
-/// }
-///
-/// impl<'info> SetCount<'info> {
-///     pub fn accounts(counter: &Counter, ctx: &Context<SetCount>) -> Result<()> {
-///         if ctx.accounts.auth_program.key != &counter.auth_program {
-///             return Err(error!(ErrorCode::InvalidAuthProgram));
-///         }
-///         Ok(())
-///     }
-/// }
-///
-/// #[error_code]
-/// pub enum ErrorCode {
-///     #[msg("Invalid auth program.")]
-///     InvalidAuthProgram,
-/// }
-///```
-///
-/// ## Defining an implementation
-///
-/// Now we define the program that implements the interface, which the above
-/// program will call.
-///
-/// ```ignore
-/// use anchor_lang::prelude::*;
-/// use counter::Auth;
-///
-/// #[program]
-/// pub mod counter_auth {
-///     use super::*;
-///
-///     #[state]
-///     pub struct CounterAuth;
-///
-///     impl<'info> Auth<'info, Empty> for CounterAuth {
-///         fn is_authorized(_ctx: Context<Empty>, current: u64, new: u64) -> Result<()> {
-///             if current % 2 == 0 {
-///                 if new % 2 == 0 {
-///                     return Err(ProgramError::Custom(50).into()); // Arbitrary error code.
-///                 }
-///             } else {
-///                 if new % 2 == 1 {
-///                     return Err(ProgramError::Custom(60).into()); // Arbitrary error code.
-///                 }
-///             }
-///             Ok(())
-///         }
-///     }
-/// }
-/// #[derive(Accounts)]
-/// pub struct Empty {}
-/// ```
-///
-/// # Returning Values Across CPI
-///
-/// The caller above uses a `Result` to act as a boolean. However, in order
-/// for this feature to be maximally useful, we need a way to return values from
-/// interfaces. For now, one can do this by writing to a shared account, e.g.,
-/// with the SPL's [Shared Memory Program](https://github.com/solana-labs/solana-program-library/tree/master/shared-memory).
-/// In the future, Anchor will add the ability to return values across CPI
-/// without having to worry about the details of shared memory accounts.
-#[proc_macro_attribute]
-pub fn interface(
-    _args: proc_macro::TokenStream,
-    input: proc_macro::TokenStream,
-) -> proc_macro::TokenStream {
-    let item_trait = parse_macro_input!(input as syn::ItemTrait);
-
-    let trait_name = item_trait.ident.to_string();
-    let mod_name: proc_macro2::TokenStream = item_trait
-        .ident
-        .to_string()
-        .to_snake_case()
-        .parse()
-        .unwrap();
-
-    let methods: Vec<proc_macro2::TokenStream> = item_trait
-        .items
-        .iter()
-        .filter_map(|trait_item: &syn::TraitItem| match trait_item {
-            syn::TraitItem::Method(m) => Some(m),
-            _ => None,
-        })
-        .map(|method: &syn::TraitItemMethod| {
-            let method_name = &method.sig.ident;
-            let args: Vec<&syn::PatType> = method
-                .sig
-                .inputs
-                .iter()
-                .filter_map(|arg: &syn::FnArg| match arg {
-                    syn::FnArg::Typed(pat_ty) => Some(pat_ty),
-                    // TODO: just map this to None once we allow this feature.
-                    _ => panic!("Invalid syntax. No self allowed."),
-                })
-                .filter(|pat_ty| {
-                    let mut ty = parser::tts_to_string(&pat_ty.ty);
-                    ty.retain(|s| !s.is_whitespace());
-                    !ty.starts_with("Context<")
-                })
-                .collect();
-            let args_no_tys: Vec<&Box<syn::Pat>> = args
-                .iter()
-                .map(|arg| {
-                    &arg.pat
-                })
-                .collect();
-            let args_struct = {
-                if args.is_empty() {
-                    quote! {
-                        use anchor_lang::prelude::borsh;
-                        #[derive(anchor_lang::AnchorSerialize, anchor_lang::AnchorDeserialize)]
-                        struct Args;
-                    }
-                } else {
-                    quote! {
-                        use anchor_lang::prelude::borsh;
-                        #[derive(anchor_lang::AnchorSerialize, anchor_lang::AnchorDeserialize)]
-                        struct Args {
-                            #(#args),*
-                        }
-                    }
-                }
-            };
-
-            let sighash_arr = anchor_syn::codegen::program::common::sighash(&trait_name, &method_name.to_string());
-            let sighash_tts: proc_macro2::TokenStream =
-                format!("{:?}", sighash_arr).parse().unwrap();
-            quote! {
-                pub fn #method_name<'a,'b, 'c, 'info, T: anchor_lang::Accounts<'info> + anchor_lang::ToAccountMetas + anchor_lang::ToAccountInfos<'info>>(
-                    ctx: anchor_lang::context::CpiContext<'a, 'b, 'c, 'info, T>,
-                    #(#args),*
-                ) -> anchor_lang::Result<()> {
-                    #args_struct
-
-                    let ix = {
-                        let ix = Args {
-                            #(#args_no_tys),*
-                        };
-                        let mut ix_data = anchor_lang::AnchorSerialize::try_to_vec(&ix)
-                            .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotSerialize)?;
-                        let mut data = #sighash_tts.to_vec();
-                        data.append(&mut ix_data);
-                        let accounts = ctx.to_account_metas(None);
-                        anchor_lang::solana_program::instruction::Instruction {
-                            program_id: *ctx.program.key,
-                            accounts,
-                            data,
-                        }
-                    };
-                    let mut acc_infos = ctx.to_account_infos();
-                    acc_infos.push(ctx.program.clone());
-                    anchor_lang::solana_program::program::invoke_signed(
-                        &ix,
-                        &acc_infos,
-                        ctx.signer_seeds,
-                    ).map_err(Into::into)
-                }
-            }
-        })
-        .collect();
-
-    proc_macro::TokenStream::from(quote! {
-        #item_trait
-
-        /// Anchor generated module for invoking programs implementing an
-        /// `#[interface]` via CPI.
-        mod #mod_name {
-            use super::*;
-            #(#methods)*
-        }
-    })
-}

+ 0 - 22
lang/attribute/state/Cargo.toml

@@ -1,22 +0,0 @@
-[package]
-name = "anchor-attribute-state"
-version = "0.26.0"
-authors = ["Serum Foundation <foundation@projectserum.com>"]
-repository = "https://github.com/coral-xyz/anchor"
-license = "Apache-2.0"
-description = "Attribute for defining a program state struct"
-rust-version = "1.59"
-edition = "2021"
-
-[lib]
-proc-macro = true
-
-[features]
-anchor-debug = ["anchor-syn/anchor-debug"]
-
-[dependencies]
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0.60", features = ["full"] }
-anyhow = "1.0.32"
-anchor-syn = { path = "../../syn", version = "0.26.0" }

+ 0 - 92
lang/attribute/state/src/lib.rs

@@ -1,92 +0,0 @@
-extern crate proc_macro;
-
-use quote::quote;
-use syn::parse_macro_input;
-
-/// The `#[state]` attribute defines the program's state struct, i.e., the
-/// program's global account singleton giving the program the illusion of state.
-///
-/// To allocate space into the account on initialization, pass in the account
-/// size into the macro, e.g., `#[state(SIZE)]`. Otherwise, the size of the
-/// account returned by the struct's `new` constructor will determine the
-/// account size. When determining a size, make sure to reserve enough space
-/// for the 8 byte account discriminator prepended to the account. That is,
-/// always use 8 extra bytes.
-///
-/// # Zero Copy Deserialization
-///
-/// Similar to the `#[account]` attribute one can enable zero copy
-/// deserialization by using the `zero_copy` argument:
-///
-/// ```ignore
-/// #[state(zero_copy)]
-/// ```
-///
-/// For more, see the [`account`](./attr.account.html) attribute.
-#[deprecated(
-    since = "0.14.0",
-    note = "#[state] will be removed in a future version. Use a PDA with static seeds instead"
-)]
-#[proc_macro_attribute]
-pub fn state(
-    args: proc_macro::TokenStream,
-    input: proc_macro::TokenStream,
-) -> proc_macro::TokenStream {
-    let item_struct = parse_macro_input!(input as syn::ItemStruct);
-    let struct_ident = &item_struct.ident;
-    let is_zero_copy = args.to_string() == "zero_copy";
-
-    let size_override = {
-        if args.is_empty() {
-            // No size override given. The account size is whatever is given
-            // as the initialized value. Use the default implementation.
-            quote! {
-                impl anchor_lang::__private::AccountSize for #struct_ident {
-                    fn size(&self) -> anchor_lang::Result<u64> {
-                        Ok(8 + self
-                            .try_to_vec()
-                            .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotSerialize)?
-                            .len() as u64)
-                    }
-                }
-            }
-        } else if is_zero_copy {
-            quote! {
-                impl anchor_lang::__private::AccountSize for #struct_ident {
-                    fn size(&self) -> anchor_lang::Result<u64> {
-                        let len = anchor_lang::__private::bytemuck::bytes_of(self).len() as u64;
-                        Ok(8 + len)
-                    }
-                }
-            }
-        } else {
-            let size = proc_macro2::TokenStream::from(args);
-            // Size override given to the macro. Use it.
-            quote! {
-                impl anchor_lang::__private::AccountSize for #struct_ident {
-                    fn size(&self) -> anchor_lang::Result<u64> {
-                        Ok(#size)
-                    }
-                }
-            }
-        }
-    };
-
-    let attribute = match is_zero_copy {
-        false => quote! {
-            #[cfg_attr(feature = "anchor-deprecated-state", account)]
-            #[cfg_attr(not(feature = "anchor-deprecated-state"), account("state"))]
-        },
-        true => quote! {
-            #[cfg_attr(feature = "anchor-deprecated-state", account(zero_copy))]
-            #[cfg_attr(not(feature = "anchor-deprecated-state"), account("state", zero_copy))]
-        },
-    };
-
-    proc_macro::TokenStream::from(quote! {
-        #attribute
-        #item_struct
-
-        #size_override
-    })
-}

+ 0 - 149
lang/src/accounts/cpi_state.rs

@@ -1,149 +0,0 @@
-use crate::error::ErrorCode;
-#[allow(deprecated)]
-use crate::{accounts::state::ProgramState, context::CpiStateContext};
-use crate::{
-    AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Key, Result, ToAccountInfos,
-    ToAccountMetas,
-};
-use solana_program::account_info::AccountInfo;
-use solana_program::instruction::AccountMeta;
-use solana_program::pubkey::Pubkey;
-use std::collections::{BTreeMap, BTreeSet};
-use std::ops::{Deref, DerefMut};
-
-/// Boxed container for the program state singleton, used when the state
-/// is for a program not currently executing.
-#[derive(Clone)]
-#[deprecated]
-pub struct CpiState<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    inner: Box<Inner<'info, T>>,
-}
-
-#[derive(Clone)]
-struct Inner<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    info: AccountInfo<'info>,
-    account: T,
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> CpiState<'info, T> {
-    pub fn new(i: AccountInfo<'info>, account: T) -> CpiState<'info, T> {
-        Self {
-            inner: Box::new(Inner { info: i, account }),
-        }
-    }
-
-    /// Deserializes the given `info` into a `CpiState`.
-    #[inline(never)]
-    pub fn try_from(info: &AccountInfo<'info>) -> Result<CpiState<'info, T>> {
-        let mut data: &[u8] = &info.try_borrow_data()?;
-        Ok(CpiState::new(info.clone(), T::try_deserialize(&mut data)?))
-    }
-
-    fn seed() -> &'static str {
-        ProgramState::<T>::seed()
-    }
-
-    pub fn address(program_id: &Pubkey) -> Pubkey {
-        let (base, _nonce) = Pubkey::find_program_address(&[], program_id);
-        let seed = Self::seed();
-        let owner = program_id;
-        Pubkey::create_with_seed(&base, seed, owner).unwrap()
-    }
-
-    /// Convenience api for creating a `CpiStateContext`.
-    pub fn context<'a, 'b, 'c, A: Accounts<'info>>(
-        &self,
-        program: AccountInfo<'info>,
-        accounts: A,
-    ) -> CpiStateContext<'a, 'b, 'c, 'info, A> {
-        CpiStateContext::new(program, self.inner.info.clone(), accounts)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> Accounts<'info> for CpiState<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Clone,
-{
-    #[inline(never)]
-    fn try_accounts(
-        _program_id: &Pubkey,
-        accounts: &mut &[AccountInfo<'info>],
-        _ix_data: &[u8],
-        _bumps: &mut BTreeMap<String, u8>,
-        _reallocs: &mut BTreeSet<Pubkey>,
-    ) -> Result<Self> {
-        if accounts.is_empty() {
-            return Err(ErrorCode::AccountNotEnoughKeys.into());
-        }
-        let account = &accounts[0];
-        *accounts = &accounts[1..];
-
-        // No owner or address check is done here. One must use the
-        // #[account(state = <account-name>)] constraint.
-
-        CpiState::try_from(account)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountMetas
-    for CpiState<'info, T>
-{
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        let is_signer = is_signer.unwrap_or(self.inner.info.is_signer);
-        let meta = match self.inner.info.is_writable {
-            false => AccountMeta::new_readonly(*self.inner.info.key, is_signer),
-            true => AccountMeta::new(*self.inner.info.key, is_signer),
-        };
-        vec![meta]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountInfos<'info>
-    for CpiState<'info, T>
-{
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        vec![self.inner.info.clone()]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AsRef<AccountInfo<'info>>
-    for CpiState<'info, T>
-{
-    fn as_ref(&self) -> &AccountInfo<'info> {
-        &self.inner.info
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Deref for CpiState<'info, T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &(self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> DerefMut for CpiState<'info, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut DerefMut::deref_mut(&mut self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info>
-    for CpiState<'info, T>
-{
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for CpiState<'info, T> {
-    fn key(&self) -> Pubkey {
-        *self.inner.info.key
-    }
-}

+ 0 - 6
lang/src/accounts/mod.rs

@@ -9,9 +9,6 @@ pub mod boxed;
 pub mod cpi_account;
 #[doc(hidden)]
 #[allow(deprecated)]
-pub mod cpi_state;
-#[doc(hidden)]
-#[allow(deprecated)]
 pub mod loader;
 pub mod option;
 pub mod program;
@@ -19,9 +16,6 @@ pub mod program;
 #[allow(deprecated)]
 pub mod program_account;
 pub mod signer;
-#[doc(hidden)]
-#[allow(deprecated)]
-pub mod state;
 pub mod system_account;
 pub mod sysvar;
 pub mod unchecked_account;

+ 0 - 171
lang/src/accounts/state.rs

@@ -1,171 +0,0 @@
-#[allow(deprecated)]
-use crate::accounts::cpi_account::CpiAccount;
-use crate::bpf_writer::BpfWriter;
-use crate::error::{Error, ErrorCode};
-use crate::{
-    AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Key, Result, ToAccountInfo,
-    ToAccountInfos, ToAccountMetas,
-};
-use solana_program::account_info::AccountInfo;
-use solana_program::instruction::AccountMeta;
-use solana_program::pubkey::Pubkey;
-use std::collections::{BTreeMap, BTreeSet};
-use std::ops::{Deref, DerefMut};
-
-pub const PROGRAM_STATE_SEED: &str = "unversioned";
-
-/// Boxed container for the program state singleton.
-#[derive(Clone)]
-#[deprecated]
-pub struct ProgramState<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    inner: Box<Inner<'info, T>>,
-}
-
-#[derive(Clone)]
-struct Inner<'info, T: AccountSerialize + AccountDeserialize + Clone> {
-    info: AccountInfo<'info>,
-    account: T,
-}
-
-#[allow(deprecated)]
-
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> ProgramState<'a, T> {
-    fn new(info: AccountInfo<'a>, account: T) -> ProgramState<'a, T> {
-        Self {
-            inner: Box::new(Inner { info, account }),
-        }
-    }
-
-    /// Deserializes the given `info` into a `ProgramState`.
-    #[inline(never)]
-    pub fn try_from(program_id: &Pubkey, info: &AccountInfo<'a>) -> Result<ProgramState<'a, T>> {
-        if info.owner != program_id {
-            return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
-                .with_pubkeys((*info.owner, *program_id)));
-        }
-        if info.key != &Self::address(program_id) {
-            solana_program::msg!("Invalid state address");
-            return Err(ErrorCode::StateInvalidAddress.into());
-        }
-        let mut data: &[u8] = &info.try_borrow_data()?;
-        Ok(ProgramState::new(
-            info.clone(),
-            T::try_deserialize(&mut data)?,
-        ))
-    }
-
-    pub fn seed() -> &'static str {
-        PROGRAM_STATE_SEED
-    }
-
-    pub fn address(program_id: &Pubkey) -> Pubkey {
-        address(program_id)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> Accounts<'info> for ProgramState<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Clone,
-{
-    #[inline(never)]
-    fn try_accounts(
-        program_id: &Pubkey,
-        accounts: &mut &[AccountInfo<'info>],
-        _ix_data: &[u8],
-        _bumps: &mut BTreeMap<String, u8>,
-        _reallocs: &mut BTreeSet<Pubkey>,
-    ) -> Result<Self> {
-        if accounts.is_empty() {
-            return Err(ErrorCode::AccountNotEnoughKeys.into());
-        }
-        let account = &accounts[0];
-        *accounts = &accounts[1..];
-        ProgramState::try_from(program_id, account)
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountMetas
-    for ProgramState<'info, T>
-{
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        let is_signer = is_signer.unwrap_or(self.inner.info.is_signer);
-        let meta = match self.inner.info.is_writable {
-            false => AccountMeta::new_readonly(*self.inner.info.key, is_signer),
-            true => AccountMeta::new(*self.inner.info.key, is_signer),
-        };
-        vec![meta]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> ToAccountInfos<'info>
-    for ProgramState<'info, T>
-{
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        vec![self.inner.info.clone()]
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AsRef<AccountInfo<'info>>
-    for ProgramState<'info, T>
-{
-    fn as_ref(&self) -> &AccountInfo<'info> {
-        &self.inner.info
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> Deref for ProgramState<'a, T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &(self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, T: AccountSerialize + AccountDeserialize + Clone> DerefMut for ProgramState<'a, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut DerefMut::deref_mut(&mut self.inner).account
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T> From<CpiAccount<'info, T>> for ProgramState<'info, T>
-where
-    T: AccountSerialize + AccountDeserialize + Clone,
-{
-    fn from(a: CpiAccount<'info, T>) -> Self {
-        Self::new(a.to_account_info(), Deref::deref(&a).clone())
-    }
-}
-
-#[allow(deprecated)]
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info>
-    for ProgramState<'info, T>
-{
-    fn exit(&self, _program_id: &Pubkey) -> Result<()> {
-        let info = self.to_account_info();
-        let mut data = info.try_borrow_mut_data()?;
-        let dst: &mut [u8] = &mut data;
-        let mut writer = BpfWriter::new(dst);
-        self.inner.account.try_serialize(&mut writer)?;
-        Ok(())
-    }
-}
-
-pub fn address(program_id: &Pubkey) -> Pubkey {
-    let (base, _nonce) = Pubkey::find_program_address(&[], program_id);
-    let seed = PROGRAM_STATE_SEED;
-    let owner = program_id;
-    Pubkey::create_with_seed(&base, seed, owner).unwrap()
-}
-
-impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for ProgramState<'info, T> {
-    fn key(&self) -> Pubkey {
-        *self.inner.info.key
-    }
-}

+ 0 - 82
lang/src/context.rs

@@ -241,85 +241,3 @@ impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountMetas
         metas
     }
 }
-
-/// Context specifying non-argument inputs for cross-program-invocations
-/// targeted at program state instructions.
-#[doc(hidden)]
-#[deprecated]
-pub struct CpiStateContext<'a, 'b, 'c, 'info, T: Accounts<'info>> {
-    state: AccountInfo<'info>,
-    cpi_ctx: CpiContext<'a, 'b, 'c, 'info, T>,
-}
-
-#[allow(deprecated)]
-impl<'a, 'b, 'c, 'info, T: Accounts<'info>> CpiStateContext<'a, 'b, 'c, 'info, T> {
-    pub fn new(program: AccountInfo<'info>, state: AccountInfo<'info>, accounts: T) -> Self {
-        Self {
-            state,
-            cpi_ctx: CpiContext {
-                accounts,
-                program,
-                signer_seeds: &[],
-                remaining_accounts: Vec::new(),
-            },
-        }
-    }
-
-    pub fn new_with_signer(
-        program: AccountInfo<'info>,
-        state: AccountInfo<'info>,
-        accounts: T,
-        signer_seeds: &'a [&'b [&'c [u8]]],
-    ) -> Self {
-        Self {
-            state,
-            cpi_ctx: CpiContext {
-                accounts,
-                program,
-                signer_seeds,
-                remaining_accounts: Vec::new(),
-            },
-        }
-    }
-
-    #[must_use]
-    pub fn with_signer(mut self, signer_seeds: &'a [&'b [&'c [u8]]]) -> Self {
-        self.cpi_ctx = self.cpi_ctx.with_signer(signer_seeds);
-        self
-    }
-
-    pub fn program(&self) -> &AccountInfo<'info> {
-        &self.cpi_ctx.program
-    }
-
-    pub fn signer_seeds(&self) -> &[&[&[u8]]] {
-        self.cpi_ctx.signer_seeds
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, 'b, 'c, 'info, T: Accounts<'info>> ToAccountMetas
-    for CpiStateContext<'a, 'b, 'c, 'info, T>
-{
-    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
-        // State account is always first for state instructions.
-        let mut metas = vec![match self.state.is_writable {
-            false => AccountMeta::new_readonly(*self.state.key, false),
-            true => AccountMeta::new(*self.state.key, false),
-        }];
-        metas.append(&mut self.cpi_ctx.accounts.to_account_metas(is_signer));
-        metas
-    }
-}
-
-#[allow(deprecated)]
-impl<'a, 'b, 'c, 'info, T: Accounts<'info>> ToAccountInfos<'info>
-    for CpiStateContext<'a, 'b, 'c, 'info, T>
-{
-    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
-        let mut infos = self.cpi_ctx.accounts.to_account_infos();
-        infos.push(self.state.clone());
-        infos.push(self.cpi_ctx.program.clone());
-        infos
-    }
-}

+ 2 - 8
lang/src/error.rs

@@ -12,7 +12,6 @@ pub const ERROR_CODE_OFFSET: u32 = 6000;
 /// - &gt;= 1000 IDL error codes
 /// - &gt;= 2000 constraint error codes
 /// - &gt;= 3000 account error codes
-/// - = 4000 state error code
 /// - &gt;= 4100 misc error codes
 /// - = 5000 deprecated error code
 ///
@@ -67,8 +66,8 @@ pub enum ErrorCode {
     /// 2007 - An executable constraint was violated
     #[msg("An executable constraint was violated")]
     ConstraintExecutable,
-    /// 2008 - A state constraint was violated
-    #[msg("A state constraint was violated")]
+    /// 2008 - Deprecated Error, feel free to replace with something else
+    #[msg("Deprecated Error, feel free to replace with something else")]
     ConstraintState,
     /// 2009 - An associated constraint was violated
     #[msg("An associated constraint was violated")]
@@ -188,11 +187,6 @@ pub enum ErrorCode {
     #[msg("The account was duplicated for more than one reallocation")]
     AccountDuplicateReallocs,
 
-    // State.
-    /// 4000 - The given state account does not have the correct address
-    #[msg("The given state account does not have the correct address")]
-    StateInvalidAddress = 4000,
-
     // Miscellaneous
     /// 4100 - The declared program id does not match actual program id
     #[msg("The declared program id does not match the actual program id")]

+ 3 - 20
lang/src/lib.rs

@@ -49,9 +49,7 @@ pub use anchor_attribute_account::{account, declare_id, zero_copy};
 pub use anchor_attribute_constant::constant;
 pub use anchor_attribute_error::*;
 pub use anchor_attribute_event::{emit, event};
-pub use anchor_attribute_interface::interface;
 pub use anchor_attribute_program::program;
-pub use anchor_attribute_state::state;
 pub use anchor_derive_accounts::Accounts;
 /// Borsh is the default serialization format for instructions and accounts.
 pub use borsh::{BorshDeserialize as AnchorDeserialize, BorshSerialize as AnchorSerialize};
@@ -245,9 +243,9 @@ pub mod prelude {
         accounts::account_loader::AccountLoader, accounts::program::Program,
         accounts::signer::Signer, accounts::system_account::SystemAccount,
         accounts::sysvar::Sysvar, accounts::unchecked_account::UncheckedAccount, constant,
-        context::Context, context::CpiContext, declare_id, emit, err, error, event, interface,
-        program, require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
-        require_neq, solana_program::bpf_loader_upgradeable::UpgradeableLoaderState, source, state,
+        context::Context, context::CpiContext, declare_id, emit, err, error, event, program,
+        require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
+        require_neq, solana_program::bpf_loader_upgradeable::UpgradeableLoaderState, source,
         system_program::System, zero_copy, AccountDeserialize, AccountSerialize, Accounts,
         AccountsClose, AccountsExit, AnchorDeserialize, AnchorSerialize, Id, Key, Owner,
         ProgramData, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas,
@@ -275,7 +273,6 @@ pub mod prelude {
 /// Internal module used by macros and unstable apis.
 #[doc(hidden)]
 pub mod __private {
-    use super::Result;
     /// The discriminator anchor uses to mark an account as closed.
     pub const CLOSED_ACCOUNT_DISCRIMINATOR: [u8; 8] = [255, 255, 255, 255, 255, 255, 255, 255];
 
@@ -291,17 +288,6 @@ pub mod __private {
 
     use solana_program::pubkey::Pubkey;
 
-    pub mod state {
-        pub use crate::accounts::state::*;
-    }
-
-    // Calculates the size of an account, which may be larger than the deserialized
-    // data in it. This trait is currently only used for `#[state]` accounts.
-    #[doc(hidden)]
-    pub trait AccountSize {
-        fn size(&self) -> Result<u64>;
-    }
-
     // Very experimental trait.
     #[doc(hidden)]
     pub trait ZeroCopyAccessor<Ty> {
@@ -318,9 +304,6 @@ pub mod __private {
             input.to_bytes()
         }
     }
-
-    #[doc(hidden)]
-    pub use crate::accounts::state::PROGRAM_STATE_SEED;
 }
 
 /// Ensures a condition is true, otherwise returns with the given error.

+ 0 - 34
lang/syn/src/codegen/accounts/constraints.rs

@@ -84,7 +84,6 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
         rent_exempt,
         seeds,
         executable,
-        state,
         close,
         address,
         associated_token,
@@ -128,9 +127,6 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
     if let Some(c) = executable {
         constraints.push(Constraint::Executable(c));
     }
-    if let Some(c) = state {
-        constraints.push(Constraint::State(c));
-    }
     if let Some(c) = close {
         constraints.push(Constraint::Close(c));
     }
@@ -163,7 +159,6 @@ fn generate_constraint(
         Constraint::RentExempt(c) => generate_constraint_rent_exempt(f, c),
         Constraint::Seeds(c) => generate_constraint_seeds(f, c),
         Constraint::Executable(c) => generate_constraint_executable(f, c),
-        Constraint::State(c) => generate_constraint_state(f, c, accs),
         Constraint::Close(c) => generate_constraint_close(f, c, accs),
         Constraint::Address(c) => generate_constraint_address(f, c),
         Constraint::AssociatedToken(c) => generate_constraint_associated_token(f, c, accs),
@@ -1142,35 +1137,6 @@ pub fn generate_constraint_executable(
     }
 }
 
-pub fn generate_constraint_state(
-    f: &Field,
-    c: &ConstraintState,
-    accs: &AccountsStruct,
-) -> proc_macro2::TokenStream {
-    let program_target = c.program_target.clone();
-    let ident = &f.ident;
-    let name_str = ident.to_string();
-    let account_ty = match &f.ty {
-        Ty::CpiState(ty) => &ty.account_type_path,
-        _ => panic!("Invalid state constraint"),
-    };
-    let program_target_optional_check =
-        OptionalCheckScope::new_with_field(accs, ident).generate_check(quote! {#program_target});
-    quote! {
-        {
-            #program_target_optional_check
-            // Checks the given state account is the canonical state account for
-            // the target program.
-            if #ident.key() != anchor_lang::accounts::cpi_state::CpiState::<#account_ty>::address(&#program_target.key()) {
-                return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintState).with_account_name(#name_str));
-            }
-            if AsRef::<AccountInfo>::as_ref(&#ident).owner != &#program_target.key() {
-                return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintState).with_account_name(#name_str));
-            }
-        }
-    }
-}
-
 fn generate_custom_error(
     account_name: &Ident,
     custom_error: &Option<Expr>,

+ 0 - 24
lang/syn/src/codegen/program/accounts.rs

@@ -5,30 +5,6 @@ use quote::quote;
 pub fn generate(program: &Program) -> proc_macro2::TokenStream {
     let mut accounts = std::collections::HashSet::new();
 
-    // Go through state accounts.
-    if let Some(state) = &program.state {
-        // Ctor.
-        if let Some((_ctor, ctor_accounts)) = &state.ctor_and_anchor {
-            let macro_name = format!(
-                "__client_accounts_{}",
-                ctor_accounts.to_string().to_snake_case()
-            );
-            accounts.insert(macro_name);
-        }
-        // Methods.
-        if let Some((_impl_block, methods)) = &state.impl_block_and_methods {
-            for ix in methods {
-                let anchor_ident = &ix.anchor_ident;
-                // TODO: move to fn and share with accounts.rs.
-                let macro_name = format!(
-                    "__client_accounts_{}",
-                    anchor_ident.to_string().to_snake_case()
-                );
-                accounts.insert(macro_name);
-            }
-        }
-    }
-
     // Go through instruction accounts.
     for ix in &program.ixs {
         let anchor_ident = &ix.anchor_ident;

+ 1 - 45
lang/syn/src/codegen/program/common.rs

@@ -1,11 +1,7 @@
-use crate::parser;
-use crate::{IxArg, State};
+use crate::IxArg;
 use heck::CamelCase;
 use quote::quote;
 
-// Namespace for calculating state instruction sighash signatures.
-pub const SIGHASH_STATE_NAMESPACE: &str = "state";
-
 // Namespace for calculating instruction sighash signatures for any instruction
 // not affecting program state.
 pub const SIGHASH_GLOBAL_NAMESPACE: &str = "global";
@@ -22,10 +18,6 @@ pub fn sighash(namespace: &str, name: &str) -> [u8; 8] {
     sighash
 }
 
-pub fn sighash_ctor() -> [u8; 8] {
-    sighash(SIGHASH_STATE_NAMESPACE, "new")
-}
-
 pub fn generate_ix_variant(name: String, args: &[IxArg]) -> proc_macro2::TokenStream {
     let ix_arg_names: Vec<&syn::Ident> = args.iter().map(|arg| &arg.name).collect();
     let ix_name_camel: proc_macro2::TokenStream = {
@@ -45,39 +37,3 @@ pub fn generate_ix_variant(name: String, args: &[IxArg]) -> proc_macro2::TokenSt
         }
     }
 }
-
-pub fn generate_ctor_args(state: &State) -> Vec<syn::Pat> {
-    generate_ctor_typed_args(state)
-        .iter()
-        .map(|pat_ty| *pat_ty.pat.clone())
-        .collect()
-}
-
-pub fn generate_ctor_typed_args(state: &State) -> Vec<syn::PatType> {
-    state
-        .ctor_and_anchor
-        .as_ref()
-        .map(|(ctor, _anchor_ident)| {
-            ctor.sig
-                .inputs
-                .iter()
-                .filter_map(|arg: &syn::FnArg| match arg {
-                    syn::FnArg::Typed(pat_ty) => {
-                        let mut arg_str = parser::tts_to_string(&pat_ty.ty);
-                        arg_str.retain(|c| !c.is_whitespace());
-                        if arg_str.starts_with("Context<") {
-                            return None;
-                        }
-                        Some(pat_ty.clone())
-                    }
-                    _ => {
-                        if !state.is_zero_copy {
-                            panic!("Cannot pass self as parameter")
-                        }
-                        None
-                    }
-                })
-                .collect()
-        })
-        .unwrap_or_default()
-}

+ 0 - 81
lang/syn/src/codegen/program/cpi.rs

@@ -1,61 +1,9 @@
 use crate::codegen::program::common::{generate_ix_variant, sighash, SIGHASH_GLOBAL_NAMESPACE};
 use crate::Program;
-use crate::StateIx;
 use heck::SnakeCase;
 use quote::{quote, ToTokens};
 
 pub fn generate(program: &Program) -> proc_macro2::TokenStream {
-    // Generate cpi methods for the state struct.
-    // The Ctor is not exposed via CPI, since it is a one time use function.
-    let state_cpi_methods: Vec<proc_macro2::TokenStream> = program
-        .state
-        .as_ref()
-        .map(|state| {
-            state
-                .impl_block_and_methods
-                .as_ref()
-                .map(|(_, methods)| {
-                    methods
-                        .iter()
-                        .map(|method: &StateIx| {
-                            let accounts_ident = &method.anchor_ident;
-                            let ix_variant = generate_ix_variant(
-                                method.raw_method.sig.ident.to_string(),
-                                &method.args,
-                            );
-                            let method_name = &method.ident;
-                            let args: Vec<&syn::PatType> =
-                                method.args.iter().map(|arg| &arg.raw_arg).collect();
-
-                            quote! {
-                                pub fn #method_name<'a, 'b, 'c, 'info>(
-                                    ctx: anchor_lang::context::CpiStateContext<'a, 'b, 'c, 'info, #accounts_ident<'info>>,
-                                    #(#args),*
-                                ) -> anchor_lang::Result<()> {
-                                    let ix = {
-                                        let ix = instruction::state::#ix_variant;
-                                        let data = anchor_lang::InstructionData::data(&ix);
-                                        let accounts = ctx.to_account_metas(None);
-                                        anchor_lang::solana_program::instruction::Instruction {
-                                            program_id: crate::ID,
-                                            accounts,
-                                            data,
-                                        }
-                                    };
-                                    let mut acc_infos = ctx.to_account_infos();
-                                    anchor_lang::solana_program::program::invoke_signed(
-                                        &ix,
-                                        &acc_infos,
-                                        ctx.signer_seeds(),
-                                    ).map_err(Into::into)
-                                }
-                            }
-                        })
-                        .collect()
-                })
-                .unwrap_or_else(Vec::new)
-        })
-        .unwrap_or_else(Vec::new);
     // Generate cpi methods for global methods.
     let global_cpi_methods: Vec<proc_macro2::TokenStream> = program
         .ixs
@@ -123,11 +71,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
             use super::*;
             use std::marker::PhantomData;
 
-            pub mod state {
-                use super::*;
-
-                #(#state_cpi_methods)*
-            }
 
             pub struct Return<T> {
                 phantom: std::marker::PhantomData<T>
@@ -150,30 +93,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
 pub fn generate_accounts(program: &Program) -> proc_macro2::TokenStream {
     let mut accounts = std::collections::HashSet::new();
 
-    // Go through state accounts.
-    if let Some(state) = &program.state {
-        // Ctor.
-        if let Some((_ctor, ctor_accounts)) = &state.ctor_and_anchor {
-            let macro_name = format!(
-                "__cpi_client_accounts_{}",
-                ctor_accounts.to_string().to_snake_case()
-            );
-            accounts.insert(macro_name);
-        }
-        // Methods.
-        if let Some((_impl_block, methods)) = &state.impl_block_and_methods {
-            for ix in methods {
-                let anchor_ident = &ix.anchor_ident;
-                // TODO: move to fn and share with accounts.rs.
-                let macro_name = format!(
-                    "__cpi_client_accounts_{}",
-                    anchor_ident.to_string().to_snake_case()
-                );
-                accounts.insert(macro_name);
-            }
-        }
-    }
-
     // Go through instruction accounts.
     for ix in &program.ixs {
         let anchor_ident = &ix.anchor_ident;

+ 2 - 110
lang/syn/src/codegen/program/dispatch.rs

@@ -1,110 +1,8 @@
-use crate::codegen::program::common::*;
 use crate::Program;
 use heck::CamelCase;
 use quote::quote;
 
 pub fn generate(program: &Program) -> proc_macro2::TokenStream {
-    // Dispatch the state constructor.
-    let ctor_state_dispatch_arm = match &program.state {
-        None => quote! { /* no-op */ },
-        Some(state) => match state.ctor_and_anchor.is_some() {
-            false => quote! {},
-            true => {
-                let sighash_arr = sighash_ctor();
-                let sighash_tts: proc_macro2::TokenStream =
-                    format!("{:?}", sighash_arr).parse().unwrap();
-                quote! {
-                    #sighash_tts => {
-                        __private::__state::__ctor(
-                            program_id,
-                            accounts,
-                            ix_data,
-                        )
-                    }
-                }
-            }
-        },
-    };
-
-    // Dispatch the state impl instructions.
-    let state_dispatch_arms: Vec<proc_macro2::TokenStream> = match &program.state {
-        None => vec![],
-        Some(s) => s
-            .impl_block_and_methods
-            .as_ref()
-            .map(|(_impl_block, methods)| {
-                methods
-                    .iter()
-                    .map(|ix: &crate::StateIx| {
-                        let ix_method_name: proc_macro2::TokenStream =
-                            format!("__{}", ix.raw_method.sig.ident).parse().expect(
-                                "Failed to parse ix method name with `__` as `TokenStream`",
-                            );
-
-                        let ix_name_camel: proc_macro2::TokenStream = ix
-                            .raw_method
-                            .sig
-                            .ident
-                            .to_string()
-                            .as_str()
-                            .to_camel_case()
-                            .parse()
-                            .expect(
-                                "Failed to parse state ix method name in camel as `TokenStream`",
-                            );
-
-                        quote! {
-                            instruction::state::#ix_name_camel::DISCRIMINATOR => {
-                                __private::__state::#ix_method_name(
-                                    program_id,
-                                    accounts,
-                                    ix_data,
-                                )
-                            }
-                        }
-                    })
-                    .collect()
-            })
-            .unwrap_or_default(),
-    };
-
-    // Dispatch all trait interface implementations.
-    let trait_dispatch_arms: Vec<proc_macro2::TokenStream> = match &program.state {
-        None => vec![],
-        Some(s) => s
-            .interfaces
-            .as_ref()
-            .map(|interfaces| {
-                interfaces
-                    .iter()
-                    .flat_map(|iface: &crate::StateInterface| {
-                        iface
-                            .methods
-                            .iter()
-                            .map(|m: &crate::StateIx| {
-                                let sighash_arr = sighash(&iface.trait_name, &m.ident.to_string());
-                                let sighash_tts: proc_macro2::TokenStream =
-                                    format!("{:?}", sighash_arr).parse().unwrap();
-                                let name = &m.raw_method.sig.ident.to_string();
-                                let ix_method_name: proc_macro2::TokenStream =
-                                    format!("__{}_{}", iface.trait_name, name).parse().unwrap();
-                                quote! {
-                                    #sighash_tts => {
-                                        __private::__interface::#ix_method_name(
-                                            program_id,
-                                            accounts,
-                                            ix_data,
-                                        )
-                                    }
-                                }
-                            })
-                            .collect::<Vec<proc_macro2::TokenStream>>()
-                    })
-                    .collect()
-            })
-            .unwrap_or_default(),
-    };
-
     // Dispatch all global instructions.
     let global_dispatch_arms: Vec<proc_macro2::TokenStream> = program
         .ixs
@@ -142,11 +40,8 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
         ///
         /// Sha256("<namespace>:<rust-identifier>")[..8],
         ///
-        /// where the namespace can be one of three types. 1) "global" for a
-        /// regular instruction, 2) "state" for a state struct instruction
-        /// handler and 3) a trait namespace (used in combination with the
-        /// `#[interface]` attribute), which is defined by the trait name, e..
-        /// `MyTrait`.
+        /// where the namespace can be one type. "global" for a
+        /// regular instruction.
         ///
         /// With this 8 byte identifier, Anchor performs method dispatch,
         /// matching the given 8 byte identifier to the associated method
@@ -180,9 +75,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
 
             use anchor_lang::Discriminator;
             match sighash {
-                #ctor_state_dispatch_arm
-                #(#state_dispatch_arms)*
-                #(#trait_dispatch_arms)*
                 #(#global_dispatch_arms)*
                 _ => {
                     #fallback_fn

+ 2 - 6
lang/syn/src/codegen/program/entry.rs

@@ -17,13 +17,9 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
         /// code wrapping these user defined methods into something that can be
         /// executed on Solana.
         ///
-        /// These methods fall into one of three categories, each of which
-        /// can be considered a different "namespace" of the program.
+        /// These methods fall into one categorie for now.
         ///
-        /// 1) Global methods - regular methods inside of the `#[program]`.
-        /// 2) State methods - associated methods inside a `#[state]` struct.
-        /// 3) Interface methods - methods inside a strait struct's
-        ///    implementation of an `#[interface]` trait.
+        /// Global methods - regular methods inside of the `#[program]`.
         ///
         /// Care must be taken by the codegen to prevent collisions between
         /// methods in these different namespaces. For this reason, Anchor uses

+ 1 - 549
lang/syn/src/codegen/program/handlers.rs

@@ -1,5 +1,5 @@
 use crate::codegen::program::common::*;
-use crate::{Program, State};
+use crate::Program;
 use heck::CamelCase;
 use quote::{quote, ToTokens};
 
@@ -193,520 +193,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
             }
         }
     };
-    // Constructor handler.
-    let non_inlined_ctor: proc_macro2::TokenStream = match &program.state {
-        None => quote! {},
-        Some(state) => match state.ctor_and_anchor.as_ref() {
-            None => quote! {},
-            Some((_ctor, anchor_ident)) => {
-                let ctor_untyped_args = generate_ctor_args(state);
-                let name = &state.strct.ident;
-                let mod_name = &program.name;
-                let variant_arm = generate_ctor_variant(state);
-                let ix_name: proc_macro2::TokenStream =
-                    generate_ctor_variant_name().parse().unwrap();
-                let ix_name_log = format!("Instruction: {}", ix_name);
-                if state.is_zero_copy {
-                    quote! {
-                        // One time state account initializer. Will faill on subsequent
-                        // invocations.
-                        #[inline(never)]
-                        pub fn __ctor(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> anchor_lang::Result<()> {
-                            #[cfg(not(feature = "no-log-ix-name"))]
-                            anchor_lang::prelude::msg!(#ix_name_log);
-
-                            // Deserialize instruction data.
-                            let ix = instruction::state::#ix_name::deserialize(&mut &ix_data[..])
-                                .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?;
-                            let instruction::state::#variant_arm = ix;
-
-                            let mut __bumps = std::collections::BTreeMap::new();
-                            let mut __reallocs = std::collections::BTreeSet::new();
-
-                            // Deserialize accounts.
-                            let mut remaining_accounts: &[AccountInfo] = accounts;
-                            let ctor_accounts =
-                            anchor_lang::__private::Ctor::try_accounts(program_id, &mut remaining_accounts, &[], &mut __bumps, &mut __reallocs)?;
-                            let mut ctor_user_def_accounts =
-                            #anchor_ident::try_accounts(program_id, &mut remaining_accounts, ix_data, &mut __bumps, &mut __reallocs)?;
-
-                            // Create the solana account for the ctor data.
-                            let from = ctor_accounts.from.key;
-                            let (base, nonce) = Pubkey::find_program_address(&[], ctor_accounts.program.key);
-                            let seed = anchor_lang::__private::PROGRAM_STATE_SEED;
-                            let owner = ctor_accounts.program.key;
-                            let to = Pubkey::create_with_seed(&base, seed, owner).unwrap();
-                            let space = 8 + std::mem::size_of::<#name>();
-                            let rent = Rent::get()?;
-                            let lamports = rent.minimum_balance(std::convert::TryInto::try_into(space).unwrap());
-                            let seeds = &[&[nonce][..]];
-                            let ix = anchor_lang::solana_program::system_instruction::create_account_with_seed(
-                                from,
-                                &to,
-                                &base,
-                                seed,
-                                lamports,
-                                space as u64,
-                                owner,
-                            );
-                            anchor_lang::solana_program::program::invoke_signed(
-                                &ix,
-                                &[
-                                    ctor_accounts.from.clone(),
-                                    ctor_accounts.to.clone(),
-                                    ctor_accounts.base.clone(),
-                                    ctor_accounts.system_program.clone(),
-                                ],
-                                &[seeds],
-                            )?;
-
-                            // Zero copy deserialize.
-                            let loader: anchor_lang::accounts::loader::Loader<#mod_name::#name> = anchor_lang::accounts::loader::Loader::try_from_unchecked(program_id, &ctor_accounts.to)?;
-
-                            // Invoke the ctor in a new lexical scope so that
-                            // the zero-copy RefMut gets dropped. Required
-                            // so that we can subsequently run the exit routine.
-                            {
-                                let mut instance = loader.load_init()?;
-                                instance.new(
-                                    anchor_lang::context::Context::new(
-                                        program_id,
-                                        &mut ctor_user_def_accounts,
-                                        remaining_accounts,
-                                        __bumps,
-                                    ),
-                                    #(#ctor_untyped_args),*
-                                )?;
-                            }
-
-                            // Exit routines.
-                            ctor_user_def_accounts.exit(program_id)?;
-                            loader.exit(program_id)?;
-
-                            Ok(())
-                        }
-                    }
-                } else {
-                    quote! {
-                        // One time state account initializer. Will faill on subsequent
-                        // invocations.
-                        #[inline(never)]
-                        pub fn __ctor(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> anchor_lang::Result<()> {
-                            #[cfg(not(feature = "no-log-ix-name"))]
-                            anchor_lang::prelude::msg!(#ix_name_log);
-
-                            // Deserialize instruction data.
-                            let ix = instruction::state::#ix_name::deserialize(&mut &ix_data[..])
-                                .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?;
-                            let instruction::state::#variant_arm = ix;
-
-                            let mut __bumps = std::collections::BTreeMap::new();
-                            let mut __reallocs = std::collections::BTreeSet::new();
-
-                            // Deserialize accounts.
-                            let mut remaining_accounts: &[AccountInfo] = accounts;
-                            let ctor_accounts =
-                            anchor_lang::__private::Ctor::try_accounts(program_id, &mut remaining_accounts, &[], &mut __bumps, &mut __reallocs)?;
-                            let mut ctor_user_def_accounts =
-                            #anchor_ident::try_accounts(program_id, &mut remaining_accounts, ix_data, &mut __bumps, &mut __reallocs)?;
-
-                            // Invoke the ctor.
-                            let instance = #mod_name::#name::new(
-                                anchor_lang::context::Context::new(
-                                    program_id,
-                                    &mut ctor_user_def_accounts,
-                                    remaining_accounts,
-                                    __bumps,
-                                ),
-                                #(#ctor_untyped_args),*
-                            )?;
-
-                            // Create the solana account for the ctor data.
-                            let from = ctor_accounts.from.key;
-                            let (base, nonce) = Pubkey::find_program_address(&[], ctor_accounts.program.key);
-                            let seed = anchor_lang::accounts::state::ProgramState::<#name>::seed();
-                            let owner = ctor_accounts.program.key;
-                            let to = Pubkey::create_with_seed(&base, seed, owner).unwrap();
-                            let space = anchor_lang::__private::AccountSize::size(&instance)?;
-                            let rent = Rent::get()?;
-                            let lamports = rent.minimum_balance(std::convert::TryInto::try_into(space).unwrap());
-                            let seeds = &[&[nonce][..]];
-                            let ix = anchor_lang::solana_program::system_instruction::create_account_with_seed(
-                                from,
-                                &to,
-                                &base,
-                                seed,
-                                lamports,
-                                space,
-                                owner,
-                            );
-                            anchor_lang::solana_program::program::invoke_signed(
-                                &ix,
-                                &[
-                                    ctor_accounts.from.clone(),
-                                    ctor_accounts.to.clone(),
-                                    ctor_accounts.base.clone(),
-                                    ctor_accounts.system_program.clone(),
-                                ],
-                                &[seeds],
-                            )?;
-
-                            // Serialize the state and save it to storage.
-                            ctor_user_def_accounts.exit(program_id)?;
-                            let mut data = ctor_accounts.to.try_borrow_mut_data()?;
-                            let dst: &mut [u8] = &mut data;
-                            let mut cursor = std::io::Cursor::new(dst);
-                            instance.try_serialize(&mut cursor)?;
-
-                            Ok(())
-                        }
-                    }
-                }
-            }
-        },
-    };
-
-    // State method handlers.
-    let non_inlined_state_handlers: Vec<proc_macro2::TokenStream> = match &program.state {
-        None => vec![],
-        Some(state) => state
-            .impl_block_and_methods
-            .as_ref()
-            .map(|(_impl_block, methods)| {
-                methods
-                    .iter()
-                    .map(|ix| {
-                        let ix_arg_names: Vec<&syn::Ident> =
-                            ix.args.iter().map(|arg| &arg.name).collect();
-                        let private_ix_method_name: proc_macro2::TokenStream = {
-                            let n = format!("__{}", &ix.raw_method.sig.ident.to_string());
-                            n.parse().unwrap()
-                        };
-                        let ix_method_name = &ix.raw_method.sig.ident;
-                        let state_ty: proc_macro2::TokenStream = state.name.parse().unwrap();
-                        let anchor_ident = &ix.anchor_ident;
-                        let name = &state.strct.ident;
-                        let mod_name = &program.name;
-
-                        let variant_arm =
-                            generate_ix_variant(ix.raw_method.sig.ident.to_string(), &ix.args);
-                        let ix_name = generate_ix_variant_name(ix.raw_method.sig.ident.to_string());
-                        let ix_name_log = format!("Instruction: {}", ix_name);
-
-                        if state.is_zero_copy {
-                            quote! {
-                                #[inline(never)]
-                                pub fn #private_ix_method_name(
-                                    program_id: &Pubkey,
-                                    accounts: &[AccountInfo],
-                                    ix_data: &[u8],
-                                ) -> anchor_lang::Result<()> {
-                                    #[cfg(not(feature = "no-log-ix-name"))]
-                                    anchor_lang::prelude::msg!(#ix_name_log);
-
-                                    // Deserialize instruction.
-                                    let ix = instruction::state::#ix_name::deserialize(&mut &ix_data[..])
-                                        .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?;
-                                    let instruction::state::#variant_arm = ix;
-
-                                    // Bump collector.
-                                    let mut __bumps = std::collections::BTreeMap::new();
-
-                                    // Realloc tracker
-                                    let mut __reallocs= std::collections::BTreeSet::new();
-
-                                    // Load state.
-                                    let mut remaining_accounts: &[AccountInfo] = accounts;
-                                    if remaining_accounts.is_empty() {
-                                        return Err(anchor_lang::error::ErrorCode::AccountNotEnoughKeys.into());
-                                    }
-                                    let loader: anchor_lang::accounts::loader::Loader<#mod_name::#name> = anchor_lang::accounts::loader::Loader::try_accounts(program_id, &mut remaining_accounts, &[], &mut __bumps, &mut __reallocs)?;
-
-                                    // Deserialize accounts.
-                                    let mut accounts = #anchor_ident::try_accounts(
-                                        program_id,
-                                        &mut remaining_accounts,
-                                        ix_data,
-                                        &mut __bumps,
-                                        &mut __reallocs,
-                                    )?;
-                                    let ctx =
-                                        anchor_lang::context::Context::new(
-                                            program_id,
-                                            &mut accounts,
-                                            remaining_accounts,
-                                            __bumps,
-                                        );
-
-                                    // Execute user defined function.
-                                    {
-                                        let mut state = loader.load_mut()?;
-                                        state.#ix_method_name(
-                                            ctx,
-                                            #(#ix_arg_names),*
-                                        )?;
-                                    }
-                                    // Serialize the state and save it to storage.
-                                    accounts.exit(program_id)?;
-                                    loader.exit(program_id)?;
-
-                                    Ok(())
-                                }
-                            }
-                        } else {
-                            quote! {
-                                #[inline(never)]
-                                pub fn #private_ix_method_name(
-                                    program_id: &Pubkey,
-                                    accounts: &[AccountInfo],
-                                    ix_data: &[u8],
-                                ) -> anchor_lang::Result<()> {
-                                    #[cfg(not(feature = "no-log-ix-name"))]
-                                    anchor_lang::prelude::msg!(#ix_name_log);
-
-                                    // Deserialize instruction.
-                                    let ix = instruction::state::#ix_name::deserialize(&mut &ix_data[..])
-                                        .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?;
-                                    let instruction::state::#variant_arm = ix;
-
-                                    // Bump collector.
-                                    let mut __bumps = std::collections::BTreeMap::new();
-
-                                    // Realloc tracker.
-                                    let mut __reallocs = std::collections::BTreeSet::new();
-
-                                    // Load state.
-                                    let mut remaining_accounts: &[AccountInfo] = accounts;
-                                    if remaining_accounts.is_empty() {
-                                        return Err(anchor_lang::error::ErrorCode::AccountNotEnoughKeys.into());
-                                    }
-                                    let mut state: anchor_lang::accounts::state::ProgramState<#state_ty> = anchor_lang::accounts::state::ProgramState::try_accounts(
-                                        program_id,
-                                        &mut remaining_accounts,
-                                        &[],
-                                        &mut __bumps,
-                                        &mut __reallocs,
-                                    )?;
-
-                                    // Deserialize accounts.
-                                    let mut accounts = #anchor_ident::try_accounts(
-                                        program_id,
-                                        &mut remaining_accounts,
-                                        ix_data,
-                                        &mut __bumps,
-                                        &mut __reallocs,
-                                    )?;
-                                    let ctx =
-                                        anchor_lang::context::Context::new(
-                                            program_id,
-                                            &mut accounts,
-                                            remaining_accounts,
-                                            __bumps
-                                        );
-
-                                    // Execute user defined function.
-                                    state.#ix_method_name(
-                                        ctx,
-                                        #(#ix_arg_names),*
-                                    )?;
-
-                                    // Serialize the state and save it to storage.
-                                    accounts.exit(program_id)?;
-                                    let acc_info = state.to_account_info();
-                                    let mut data = acc_info.try_borrow_mut_data()?;
-                                    let dst: &mut [u8] = &mut data;
-                                    let mut cursor = std::io::Cursor::new(dst);
-                                    state.try_serialize(&mut cursor)?;
-
-                                    Ok(())
-                                }
-                            }
-                        }
-                    })
-                    .collect()
-            })
-            .unwrap_or_default(),
-    };
-
-    // State trait handlers.
-    let non_inlined_state_trait_handlers: Vec<proc_macro2::TokenStream> = match &program.state {
-        None => Vec::new(),
-        Some(state) => state
-            .interfaces
-            .as_ref()
-            .map(|interfaces| {
-                interfaces
-                    .iter()
-                    .flat_map(|iface: &crate::StateInterface| {
-                        iface
-                            .methods
-                            .iter()
-                            .map(|ix| {
-                                // Easy to implement. Just need to write a test.
-                                // Feel free to open a PR.
-                                assert!(!state.is_zero_copy, "Trait implementations not yet implemented for zero copy state structs. Please file an issue.");
-
-                                let ix_arg_names: Vec<&syn::Ident> =
-                                    ix.args.iter().map(|arg| &arg.name).collect();
-                                let private_ix_method_name: proc_macro2::TokenStream = {
-                                    let n = format!("__{}_{}", iface.trait_name, &ix.raw_method.sig.ident.to_string());
-                                    n.parse().unwrap()
-                                };
-                                let ix_method_name = &ix.raw_method.sig.ident;
-                                let state_ty: proc_macro2::TokenStream = state.name.parse().unwrap();
-                                let anchor_ident = &ix.anchor_ident;
-                                let ix_name = generate_ix_variant_name(ix.raw_method.sig.ident.to_string());
-                                let ix_name_log = format!("Instruction: {}", ix_name);
-
-                                let raw_args: Vec<&syn::PatType> = ix
-                                    .args
-                                    .iter()
-                                    .map(|arg: &crate::IxArg| &arg.raw_arg)
-                                    .collect();
-                                let args_struct = {
-                                    if ix.args.is_empty() {
-                                        quote! {
-                                            #[derive(anchor_lang::AnchorSerialize, anchor_lang::AnchorDeserialize)]
-                                            struct Args;
-                                        }
-                                    } else {
-                                        quote! {
-                                            #[derive(anchor_lang::AnchorSerialize, anchor_lang::AnchorDeserialize)]
-                                            struct Args {
-                                                #(#raw_args),*
-                                            }
-                                        }
-                                    }
-                                };
-
-                                let deserialize_instruction = quote! {
-                                    #args_struct
-                                    let ix = Args::deserialize(&mut &ix_data[..])
-                                        .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?;
-                                    let Args {
-                                        #(#ix_arg_names),*
-                                    } = ix;
-                                };
-
-                                if ix.has_receiver {
-                                    quote! {
-                                        #[inline(never)]
-                                        pub fn #private_ix_method_name(
-                                            program_id: &Pubkey,
-                                            accounts: &[AccountInfo],
-                                            ix_data: &[u8],
-                                        ) -> anchor_lang::Result<()> {
-                                            #[cfg(not(feature = "no-log-ix-name"))]
-                                            anchor_lang::prelude::msg!(#ix_name_log);
-
-                                            // Deserialize instruction.
-                                            #deserialize_instruction
-
-                                            // Bump collector.
-                                            let mut __bumps = std::collections::BTreeMap::new();
-
-                                            // Realloc tracker.
-                                            let mut __reallocs= std::collections::BTreeSet::new();
-
-                                            // Deserialize the program state account.
-                                            let mut remaining_accounts: &[AccountInfo] = accounts;
-                                            if remaining_accounts.is_empty() {
-                                                return Err(anchor_lang::error::ErrorCode::AccountNotEnoughKeys.into());
-                                            }
-                                            let mut state: anchor_lang::accounts::state::ProgramState<#state_ty> = anchor_lang::accounts::state::ProgramState::try_accounts(
-                                                program_id,
-                                                &mut remaining_accounts,
-                                                &[],
-                                                &mut __bumps,
-                                                &mut __reallocs,
-                                            )?;
-
-                                            // Deserialize accounts.
-                                            let mut accounts = #anchor_ident::try_accounts(
-                                                program_id,
-                                                &mut remaining_accounts,
-                                                ix_data,
-                                                &mut __bumps,
-                                                &mut __reallocs,
-                                            )?;
-                                            let ctx =
-                                                anchor_lang::context::Context::new(
-                                                    program_id,
-                                                    &mut accounts,
-                                                    remaining_accounts,
-                                                    __bumps,
-                                                );
-
-                                            // Execute user defined function.
-                                            state.#ix_method_name(
-                                                ctx,
-                                                #(#ix_arg_names),*
-                                            )?;
-
-                                            // Exit procedures.
-                                            accounts.exit(program_id)?;
-                                            let acc_info = state.to_account_info();
-                                            let mut data = acc_info.try_borrow_mut_data()?;
-                                            let dst: &mut [u8] = &mut data;
-                                            let mut cursor = std::io::Cursor::new(dst);
-                                            state.try_serialize(&mut cursor)?;
-
-                                            Ok(())
-                                        }
-                                    }
-                                } else {
-                                    let state_name: proc_macro2::TokenStream = state.name.parse().unwrap();
-                                    quote! {
-                                        #[inline(never)]
-                                        pub fn #private_ix_method_name(
-                                            program_id: &Pubkey,
-                                            accounts: &[AccountInfo],
-                                            ix_data: &[u8],
-                                        ) -> anchor_lang::Result<()> {
-                                            #[cfg(not(feature = "no-log-ix-name"))]
-                                            anchor_lang::prelude::msg!(#ix_name_log);
-
-                                            // Deserialize instruction.
-                                            #deserialize_instruction
-
-                                            // Bump collector.
-                                            let mut __bumps = std::collections::BTreeMap::new();
-
-                                            let mut __reallocs = std::collections::BTreeSet::new();
-
-                                            // Deserialize accounts.
-                                            let mut remaining_accounts: &[AccountInfo] = accounts;
-                                            let mut accounts = #anchor_ident::try_accounts(
-                                                program_id,
-                                                &mut remaining_accounts,
-                                                ix_data,
-                                                &mut __bumps,
-                                                &mut __reallocs,
-                                            )?;
-
-                                            // Execute user defined function.
-                                            #state_name::#ix_method_name(
-                                                anchor_lang::context::Context::new(
-                                                    program_id,
-                                                    &mut accounts,
-                                                    remaining_accounts,
-                                                    __bumps
-                                                ),
-                                                #(#ix_arg_names),*
-                                            )?;
-
-                                            // Exit procedure.
-                                            accounts.exit(program_id)
-                                        }
-                                    }
-                                }
-                            })
-                            .collect::<Vec<proc_macro2::TokenStream>>()
-                    })
-                    .collect()
-            })
-            .unwrap_or_default(),
-    };
 
     let non_inlined_handlers: Vec<proc_macro2::TokenStream> = program
         .ixs
@@ -789,21 +275,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
                 #non_inlined_idl
             }
 
-            /// __state mod defines wrapped handlers for state instructions.
-            pub mod __state {
-                use super::*;
-
-                #non_inlined_ctor
-                #(#non_inlined_state_handlers)*
-            }
 
-            /// __interface mod defines wrapped handlers for `#[interface]` trait
-            /// implementations.
-            pub mod __interface {
-                use super::*;
-
-                #(#non_inlined_state_trait_handlers)*
-            }
 
             /// __global mod defines wrapped handlers for global instructions.
             pub mod __global {
@@ -819,23 +291,3 @@ fn generate_ix_variant_name(name: String) -> proc_macro2::TokenStream {
     let n = name.to_camel_case();
     n.parse().unwrap()
 }
-
-fn generate_ctor_variant_name() -> String {
-    "New".to_string()
-}
-
-fn generate_ctor_variant(state: &State) -> proc_macro2::TokenStream {
-    let ctor_args = generate_ctor_args(state);
-    let ctor_variant_name: proc_macro2::TokenStream = generate_ctor_variant_name().parse().unwrap();
-    if ctor_args.is_empty() {
-        quote! {
-            #ctor_variant_name
-        }
-    } else {
-        quote! {
-            #ctor_variant_name {
-                #(#ctor_args),*
-            }
-        }
-    }
-}

+ 0 - 123
lang/syn/src/codegen/program/instruction.rs

@@ -5,122 +5,6 @@ use heck::CamelCase;
 use quote::quote;
 
 pub fn generate(program: &Program) -> proc_macro2::TokenStream {
-    let ctor_variant = match &program.state {
-        None => quote! {},
-        Some(state) => {
-            let ctor_args: Vec<proc_macro2::TokenStream> = generate_ctor_typed_args(state)
-                .iter()
-                .map(|arg| {
-                    format!("pub {}", parser::tts_to_string(arg))
-                        .parse()
-                        .unwrap()
-                })
-                .collect();
-            let strct = {
-                if ctor_args.is_empty() {
-                    quote! {
-                        #[derive(AnchorSerialize, AnchorDeserialize)]
-                        pub struct New;
-                    }
-                } else {
-                    quote! {
-                        #[derive(AnchorSerialize, AnchorDeserialize)]
-                        pub struct New {
-                            #(#ctor_args),*
-                        }
-                    }
-                }
-            };
-            let sighash_arr = sighash_ctor();
-            let sighash_tts: proc_macro2::TokenStream =
-                format!("{:?}", sighash_arr).parse().unwrap();
-            quote! {
-                /// Instruction arguments to the `#[state]`'s `new`
-                /// constructor.
-                #strct
-
-                impl anchor_lang::Discriminator for New {
-                    const DISCRIMINATOR: [u8; 8] = #sighash_tts;
-                }
-                impl anchor_lang::InstructionData for New {}
-                impl anchor_lang::Owner for New {
-                    fn owner() -> Pubkey {
-                        ID
-                    }
-                }
-            }
-        }
-    };
-    let state_method_variants: Vec<proc_macro2::TokenStream> = match &program.state {
-        None => vec![],
-        Some(state) => state
-            .impl_block_and_methods
-            .as_ref()
-            .map(|(_impl_block, methods)| {
-                methods
-                    .iter()
-                    .map(|method| {
-                        let ix_name_camel: proc_macro2::TokenStream = method
-                            .raw_method
-                            .sig
-                            .ident
-                            .to_string()
-                            .to_camel_case()
-                            .parse()
-                            .unwrap();
-                        let raw_args: Vec<proc_macro2::TokenStream> = method
-                            .args
-                            .iter()
-                            .map(|arg| {
-                                format!("pub {}", parser::tts_to_string(&arg.raw_arg))
-                                    .parse()
-                                    .unwrap()
-                            })
-                            .collect();
-
-                        let ix_data_trait = {
-                            let name = method.raw_method.sig.ident.to_string();
-                            let sighash_arr = sighash(SIGHASH_STATE_NAMESPACE, &name);
-                            let sighash_tts: proc_macro2::TokenStream =
-                                format!("{:?}", sighash_arr).parse().unwrap();
-                            quote! {
-                                impl anchor_lang::Discriminator for #ix_name_camel {
-                                    const DISCRIMINATOR: [u8; 8] = #sighash_tts;
-                                }
-                                impl anchor_lang::InstructionData for #ix_name_camel {}
-                                impl anchor_lang::Owner for #ix_name_camel {
-                                    fn owner() -> Pubkey {
-                                        ID
-                                    }
-                                }
-                            }
-                        };
-
-                        // If no args, output a "unit" variant instead of a struct variant.
-                        if method.args.is_empty() {
-                            quote! {
-                                /// Anchor generated instruction.
-                                #[derive(AnchorSerialize, AnchorDeserialize)]
-                                pub struct #ix_name_camel;
-
-                                #ix_data_trait
-                            }
-                        } else {
-                            quote! {
-                                /// Anchor generated instruction.
-                                #[derive(AnchorSerialize, AnchorDeserialize)]
-                                pub struct #ix_name_camel {
-                                    #(#raw_args),*
-                                }
-
-                                #ix_data_trait
-                            }
-                        }
-                    })
-                    .collect()
-            })
-            .unwrap_or_default(),
-    };
     let variants: Vec<proc_macro2::TokenStream> = program
         .ixs
         .iter()
@@ -186,13 +70,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
         pub mod instruction {
             use super::*;
 
-            /// Instruction struct definitions for `#[state]` methods.
-            pub mod state {
-                use super::*;
-
-                #ctor_variant
-                #(#state_method_variants)*
-            }
 
             #(#variants)*
         }

+ 1 - 135
lang/syn/src/idl/file.rs

@@ -2,7 +2,7 @@ use crate::idl::*;
 use crate::parser::context::CrateContext;
 use crate::parser::{self, accounts, docs, error, program};
 use crate::Ty;
-use crate::{AccountField, AccountsStruct, StateIx};
+use crate::{AccountField, AccountsStruct};
 use anyhow::Result;
 use heck::MixedCase;
 use quote::ToTokens;
@@ -45,139 +45,6 @@ pub fn parse(
 
     let accs = parse_account_derives(&ctx);
 
-    let state = match p.state {
-        None => None,
-        Some(state) => match state.ctor_and_anchor {
-            None => None, // State struct defined but no implementation
-            Some((ctor, anchor_ident)) => {
-                let mut methods = state
-                    .impl_block_and_methods
-                    .map(|(_impl_block, methods)| {
-                        methods
-                            .iter()
-                            .map(|method: &StateIx| {
-                                let name = method.ident.to_string().to_mixed_case();
-                                let args = method
-                                    .args
-                                    .iter()
-                                    .map(|arg| {
-                                        let mut tts = proc_macro2::TokenStream::new();
-                                        arg.raw_arg.ty.to_tokens(&mut tts);
-                                        let doc = if !no_docs {
-                                            docs::parse(&arg.raw_arg.attrs)
-                                        } else {
-                                            None
-                                        };
-                                        let ty = tts.to_string().parse().unwrap();
-                                        IdlField {
-                                            name: arg.name.to_string().to_mixed_case(),
-                                            docs: doc,
-                                            ty,
-                                        }
-                                    })
-                                    .collect::<Vec<_>>();
-                                let accounts_strct =
-                                    accs.get(&method.anchor_ident.to_string()).unwrap();
-                                let accounts = idl_accounts(
-                                    &ctx,
-                                    accounts_strct,
-                                    &accs,
-                                    seeds_feature,
-                                    no_docs,
-                                );
-                                IdlInstruction {
-                                    name,
-                                    docs: None,
-                                    accounts,
-                                    args,
-                                    returns: None,
-                                }
-                            })
-                            .collect::<Vec<_>>()
-                    })
-                    .unwrap_or_default();
-                let ctor = {
-                    let name = "new".to_string();
-                    let args = ctor
-                        .sig
-                        .inputs
-                        .iter()
-                        .filter(|arg| match arg {
-                            syn::FnArg::Typed(pat_ty) => {
-                                // TODO: this filtering should be done in the parser.
-                                let mut arg_str = parser::tts_to_string(&pat_ty.ty);
-                                arg_str.retain(|c| !c.is_whitespace());
-                                !arg_str.starts_with("Context<")
-                            }
-                            _ => false,
-                        })
-                        .map(|arg: &syn::FnArg| match arg {
-                            syn::FnArg::Typed(arg_typed) => {
-                                let mut tts = proc_macro2::TokenStream::new();
-                                arg_typed.ty.to_tokens(&mut tts);
-                                let doc = if !no_docs {
-                                    docs::parse(&arg_typed.attrs)
-                                } else {
-                                    None
-                                };
-                                let ty = tts.to_string().parse().unwrap();
-                                IdlField {
-                                    name: parser::tts_to_string(&arg_typed.pat).to_mixed_case(),
-                                    docs: doc,
-                                    ty,
-                                }
-                            }
-                            _ => panic!("Invalid syntax"),
-                        })
-                        .collect();
-                    let accounts_strct = accs.get(&anchor_ident.to_string()).unwrap();
-                    let accounts =
-                        idl_accounts(&ctx, accounts_strct, &accs, seeds_feature, no_docs);
-                    IdlInstruction {
-                        name,
-                        docs: None,
-                        accounts,
-                        args,
-                        returns: None,
-                    }
-                };
-
-                methods.insert(0, ctor);
-
-                let strct = {
-                    let fields = match state.strct.fields {
-                        syn::Fields::Named(f_named) => f_named
-                            .named
-                            .iter()
-                            .map(|f: &syn::Field| {
-                                let mut tts = proc_macro2::TokenStream::new();
-                                f.ty.to_tokens(&mut tts);
-                                let doc = if !no_docs {
-                                    docs::parse(&f.attrs)
-                                } else {
-                                    None
-                                };
-                                let ty = tts.to_string().parse().unwrap();
-                                IdlField {
-                                    name: f.ident.as_ref().unwrap().to_string().to_mixed_case(),
-                                    docs: doc,
-                                    ty,
-                                }
-                            })
-                            .collect::<Vec<IdlField>>(),
-                        _ => panic!("State must be a struct"),
-                    };
-                    IdlTypeDefinition {
-                        name: state.name,
-                        docs: None,
-                        ty: IdlTypeDefinitionTy::Struct { fields },
-                    }
-                };
-
-                Some(IdlState { strct, methods })
-            }
-        },
-    };
     let error = parse_error_enum(&ctx).map(|mut e| error::parse(&mut e, None));
     let error_codes = error.as_ref().map(|e| {
         e.codes
@@ -292,7 +159,6 @@ pub fn parse(
         version,
         name: p.name.to_string(),
         docs: p.docs.clone(),
-        state,
         instructions,
         types,
         accounts,

+ 0 - 2
lang/syn/src/idl/mod.rs

@@ -14,8 +14,6 @@ pub struct Idl {
     #[serde(skip_serializing_if = "Vec::is_empty", default)]
     pub constants: Vec<IdlConst>,
     pub instructions: Vec<IdlInstruction>,
-    #[serde(skip_serializing_if = "Option::is_none", default)]
-    pub state: Option<IdlState>,
     #[serde(skip_serializing_if = "Vec::is_empty", default)]
     pub accounts: Vec<IdlTypeDefinition>,
     #[serde(skip_serializing_if = "Vec::is_empty", default)]

+ 2 - 63
lang/syn/src/lib.rs

@@ -14,8 +14,8 @@ use syn::punctuated::Punctuated;
 use syn::spanned::Spanned;
 use syn::token::Comma;
 use syn::{
-    Expr, Generics, Ident, ImplItemMethod, ItemEnum, ItemFn, ItemImpl, ItemMod, ItemStruct, LitInt,
-    LitStr, PatType, Token, Type, TypePath,
+    Expr, Generics, Ident, ItemEnum, ItemFn, ItemMod, ItemStruct, LitInt, LitStr, PatType, Token,
+    Type, TypePath,
 };
 
 pub mod codegen;
@@ -29,7 +29,6 @@ pub mod parser;
 
 #[derive(Debug)]
 pub struct Program {
-    pub state: Option<State>,
     pub ixs: Vec<Ix>,
     pub name: Ident,
     pub docs: Option<Vec<String>>,
@@ -56,32 +55,6 @@ impl ToTokens for Program {
     }
 }
 
-#[derive(Debug)]
-pub struct State {
-    pub name: String,
-    pub strct: ItemStruct,
-    pub ctor_and_anchor: Option<(ImplItemMethod, Ident)>,
-    pub impl_block_and_methods: Option<(ItemImpl, Vec<StateIx>)>,
-    pub interfaces: Option<Vec<StateInterface>>,
-    pub is_zero_copy: bool,
-}
-
-#[derive(Debug)]
-pub struct StateIx {
-    pub raw_method: ImplItemMethod,
-    pub ident: Ident,
-    pub args: Vec<IxArg>,
-    pub anchor_ident: Ident,
-    // True if there exists a &self on the method.
-    pub has_receiver: bool,
-}
-
-#[derive(Debug)]
-pub struct StateInterface {
-    pub trait_name: String,
-    pub methods: Vec<StateIx>,
-}
-
 #[derive(Debug)]
 pub struct Ix {
     pub raw_method: ItemFn,
@@ -449,8 +422,6 @@ impl Field {
                 anchor_lang::accounts::cpi_account::CpiAccount
             },
             Ty::Sysvar(_) => quote! { anchor_lang::accounts::sysvar::Sysvar },
-            Ty::CpiState(_) => quote! { anchor_lang::accounts::cpi_state::CpiState },
-            Ty::ProgramState(_) => quote! { anchor_lang::accounts::state::ProgramState },
             Ty::Program(_) => quote! { anchor_lang::accounts::program::Program },
             Ty::AccountInfo => quote! {},
             Ty::UncheckedAccount => quote! {},
@@ -508,18 +479,6 @@ impl Field {
                     #ident
                 }
             }
-            Ty::ProgramState(ty) => {
-                let account = &ty.account_type_path;
-                quote! {
-                    #account
-                }
-            }
-            Ty::CpiState(ty) => {
-                let account = &ty.account_type_path;
-                quote! {
-                    #account
-                }
-            }
             Ty::Sysvar(ty) => match ty {
                 SysvarTy::Clock => quote! {Clock},
                 SysvarTy::Rent => quote! {Rent},
@@ -557,8 +516,6 @@ pub struct CompositeField {
 pub enum Ty {
     AccountInfo,
     UncheckedAccount,
-    ProgramState(ProgramStateTy),
-    CpiState(CpiStateTy),
     ProgramAccount(ProgramAccountTy),
     Loader(LoaderTy),
     AccountLoader(AccountLoaderTy),
@@ -585,16 +542,6 @@ pub enum SysvarTy {
     Rewards,
 }
 
-#[derive(Debug, PartialEq, Eq)]
-pub struct ProgramStateTy {
-    pub account_type_path: TypePath,
-}
-
-#[derive(Debug, PartialEq, Eq)]
-pub struct CpiStateTy {
-    pub account_type_path: TypePath,
-}
-
 #[derive(Debug, PartialEq, Eq)]
 pub struct ProgramAccountTy {
     // The struct type of the account.
@@ -679,7 +626,6 @@ pub struct ConstraintGroup {
     rent_exempt: Option<ConstraintRentExempt>,
     seeds: Option<ConstraintSeedsGroup>,
     executable: Option<ConstraintExecutable>,
-    state: Option<ConstraintState>,
     has_one: Vec<ConstraintHasOne>,
     literal: Vec<ConstraintLiteral>,
     raw: Vec<ConstraintRaw>,
@@ -727,7 +673,6 @@ pub enum Constraint {
     Seeds(ConstraintSeedsGroup),
     AssociatedToken(ConstraintAssociatedToken),
     Executable(ConstraintExecutable),
-    State(ConstraintState),
     Close(ConstraintClose),
     Address(ConstraintAddress),
     TokenAccount(ConstraintTokenAccountGroup),
@@ -750,7 +695,6 @@ pub enum ConstraintToken {
     RentExempt(Context<ConstraintRentExempt>),
     Seeds(Context<ConstraintSeeds>),
     Executable(Context<ConstraintExecutable>),
-    State(Context<ConstraintState>),
     Close(Context<ConstraintClose>),
     Payer(Context<ConstraintPayer>),
     Space(Context<ConstraintSpace>),
@@ -878,11 +822,6 @@ pub struct ConstraintSeeds {
 #[derive(Debug, Clone)]
 pub struct ConstraintExecutable {}
 
-#[derive(Debug, Clone)]
-pub struct ConstraintState {
-    pub program_target: Ident,
-}
-
 #[derive(Debug, Clone)]
 pub struct ConstraintPayer {
     pub target: Expr,

+ 0 - 19
lang/syn/src/parser/accounts/constraints.rs

@@ -271,12 +271,6 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
                         }
                     },
                 )),
-                "state" => ConstraintToken::State(Context::new(
-                    span,
-                    ConstraintState {
-                        program_target: stream.parse()?,
-                    },
-                )),
                 "payer" => ConstraintToken::Payer(Context::new(
                     span,
                     ConstraintPayer {
@@ -340,7 +334,6 @@ pub struct ConstraintGroupBuilder<'ty> {
     pub rent_exempt: Option<Context<ConstraintRentExempt>>,
     pub seeds: Option<Context<ConstraintSeeds>>,
     pub executable: Option<Context<ConstraintExecutable>>,
-    pub state: Option<Context<ConstraintState>>,
     pub payer: Option<Context<ConstraintPayer>>,
     pub space: Option<Context<ConstraintSpace>>,
     pub close: Option<Context<ConstraintClose>>,
@@ -374,7 +367,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             rent_exempt: None,
             seeds: None,
             executable: None,
-            state: None,
             payer: None,
             space: None,
             close: None,
@@ -575,7 +567,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             rent_exempt,
             seeds,
             executable,
-            state,
             payer,
             space,
             close,
@@ -724,7 +715,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             owner: into_inner!(owner),
             rent_exempt: into_inner!(rent_exempt),
             executable: into_inner!(executable),
-            state: into_inner!(state),
             close: into_inner!(close),
             address: into_inner!(address),
             associated_token: if !is_init { associated_token } else { None },
@@ -747,7 +737,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             ConstraintToken::RentExempt(c) => self.add_rent_exempt(c),
             ConstraintToken::Seeds(c) => self.add_seeds(c),
             ConstraintToken::Executable(c) => self.add_executable(c),
-            ConstraintToken::State(c) => self.add_state(c),
             ConstraintToken::Payer(c) => self.add_payer(c),
             ConstraintToken::Space(c) => self.add_space(c),
             ConstraintToken::Close(c) => self.add_close(c),
@@ -1115,14 +1104,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
         Ok(())
     }
 
-    fn add_state(&mut self, c: Context<ConstraintState>) -> ParseResult<()> {
-        if self.state.is_some() {
-            return Err(ParseError::new(c.span(), "state already provided"));
-        }
-        self.state.replace(c);
-        Ok(())
-    }
-
     fn add_payer(&mut self, c: Context<ConstraintPayer>) -> ParseResult<()> {
         if self.init.is_none() {
             return Err(ParseError::new(

+ 1 - 19
lang/syn/src/parser/accounts/mod.rs

@@ -283,13 +283,11 @@ pub fn parse_account_field(f: &syn::Field) -> ParseResult<AccountField> {
 fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> {
     let r = matches!(
         ident_string(f)?.0.as_str(),
-        "ProgramState"
-            | "ProgramAccount"
+        "ProgramAccount"
             | "CpiAccount"
             | "Sysvar"
             | "AccountInfo"
             | "UncheckedAccount"
-            | "CpiState"
             | "Loader"
             | "AccountLoader"
             | "Account"
@@ -304,8 +302,6 @@ fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> {
 fn parse_ty(f: &syn::Field) -> ParseResult<(Ty, bool)> {
     let (ident, optional, path) = ident_string(f)?;
     let ty = match ident.as_str() {
-        "ProgramState" => Ty::ProgramState(parse_program_state(&path)?),
-        "CpiState" => Ty::CpiState(parse_cpi_state(&path)?),
         "ProgramAccount" => Ty::ProgramAccount(parse_program_account(&path)?),
         "CpiAccount" => Ty::CpiAccount(parse_cpi_account(&path)?),
         "Sysvar" => Ty::Sysvar(parse_sysvar(&path)?),
@@ -380,20 +376,6 @@ fn ident_string(f: &syn::Field) -> ParseResult<(String, bool, Path)> {
     Ok((segments.ident.to_string(), optional, path))
 }
 
-fn parse_program_state(path: &syn::Path) -> ParseResult<ProgramStateTy> {
-    let account_ident = parse_account(path)?;
-    Ok(ProgramStateTy {
-        account_type_path: account_ident,
-    })
-}
-
-fn parse_cpi_state(path: &syn::Path) -> ParseResult<CpiStateTy> {
-    let account_ident = parse_account(path)?;
-    Ok(CpiStateTy {
-        account_type_path: account_ident,
-    })
-}
-
 fn parse_cpi_account(path: &syn::Path) -> ParseResult<CpiAccountTy> {
     let account_ident = parse_account(path)?;
     Ok(CpiAccountTy {

+ 0 - 3
lang/syn/src/parser/program/mod.rs

@@ -4,14 +4,11 @@ use syn::parse::{Error as ParseError, Result as ParseResult};
 use syn::spanned::Spanned;
 
 mod instructions;
-mod state;
 
 pub fn parse(program_mod: syn::ItemMod) -> ParseResult<Program> {
-    let state = state::parse(&program_mod)?;
     let docs = docs::parse(&program_mod.attrs);
     let (ixs, fallback_fn) = instructions::parse(&program_mod)?;
     Ok(Program {
-        state,
         ixs,
         name: program_mod.ident.clone(),
         docs,

+ 0 - 315
lang/syn/src/parser/program/state.rs

@@ -1,315 +0,0 @@
-use crate::parser;
-use crate::parser::docs;
-use crate::parser::program::ctx_accounts_ident;
-use crate::{IxArg, State, StateInterface, StateIx};
-use syn::parse::{Error as ParseError, Result as ParseResult};
-use syn::spanned::Spanned;
-
-// Name of the attribute denoting a state struct.
-const STATE_STRUCT_ATTRIBUTE: &str = "state";
-
-// Reserved keyword for the constructor method.
-const CTOR_METHOD_NAME: &str = "new";
-
-// Parse the state from the program mod definition.
-pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<Option<State>> {
-    let mod_content = &program_mod
-        .content
-        .as_ref()
-        .ok_or_else(|| ParseError::new(program_mod.span(), "program content not provided"))?
-        .1;
-
-    // Parse `struct` marked with the `#[state]` attribute.
-    let strct: Option<(&syn::ItemStruct, bool)> = mod_content
-        .iter()
-        .filter_map(|item| match item {
-            syn::Item::Struct(item_strct) => {
-                let attrs = &item_strct.attrs;
-                if attrs.is_empty() {
-                    return None;
-                }
-                let attr_label = attrs[0].path.get_ident().map(|i| i.to_string());
-                if attr_label != Some(STATE_STRUCT_ATTRIBUTE.to_string()) {
-                    return None;
-                }
-                let is_zero_copy = parser::tts_to_string(&attrs[0].tokens) == "(zero_copy)";
-                Some((item_strct, is_zero_copy))
-            }
-            _ => None,
-        })
-        .next();
-
-    // Parse `impl` block for the state struct.
-    let impl_block: Option<syn::ItemImpl> = match strct {
-        None => None,
-        Some((strct, _)) => mod_content
-            .iter()
-            .filter_map(|item| match item {
-                syn::Item::Impl(item_impl) => {
-                    let impl_ty_str = parser::tts_to_string(&item_impl.self_ty);
-                    let strct_name = strct.ident.to_string();
-                    if item_impl.trait_.is_some() {
-                        return None;
-                    }
-                    if strct_name != impl_ty_str {
-                        return None;
-                    }
-                    Some(item_impl.clone())
-                }
-                _ => None,
-            })
-            .next(),
-    };
-
-    // Parse ctor and the generic type in `Context<MY-TYPE>`.
-    let ctor_and_anchor: Option<(syn::ImplItemMethod, syn::Ident)> = impl_block
-        .as_ref()
-        .map(|impl_block| {
-            let r: Option<ParseResult<_>> = impl_block
-                .items
-                .iter()
-                .filter_map(|item: &syn::ImplItem| match item {
-                    syn::ImplItem::Method(m) => match m.sig.ident == CTOR_METHOD_NAME {
-                        false => None,
-                        true => Some(m),
-                    },
-                    _ => None,
-                })
-                .map(|m: &syn::ImplItemMethod| {
-                    let (_, is_zero_copy) = strct
-                        .as_ref()
-                        .expect("impl_block exists therefore the struct exists");
-                    let ctx_arg = {
-                        if *is_zero_copy {
-                            // Second param is context.
-                            let mut iter = m.sig.inputs.iter();
-                            match iter.next() {
-                                None => {
-                                    return Err(ParseError::new(
-                                        m.sig.span(),
-                                        "first parameter must be &mut self",
-                                    ))
-                                }
-                                Some(arg) => match arg {
-                                    syn::FnArg::Receiver(r) => {
-                                        if r.mutability.is_none() {
-                                            return Err(ParseError::new(
-                                                m.sig.span(),
-                                                "first parameter must be &mut self",
-                                            ));
-                                        }
-                                    }
-                                    syn::FnArg::Typed(_) => {
-                                        return Err(ParseError::new(
-                                            m.sig.span(),
-                                            "first parameter must be &mut self",
-                                        ))
-                                    }
-                                },
-                            };
-                            match iter.next() {
-                                None => {
-                                    return Err(ParseError::new(
-                                        m.sig.span(),
-                                        "second parameter must be the Context",
-                                    ))
-                                }
-                                Some(ctx_arg) => match ctx_arg {
-                                    syn::FnArg::Receiver(_) => {
-                                        return Err(ParseError::new(
-                                            ctx_arg.span(),
-                                            "second parameter must be the Context",
-                                        ))
-                                    }
-                                    syn::FnArg::Typed(arg) => arg,
-                                },
-                            }
-                        } else {
-                            match m.sig.inputs.first() {
-                                None => {
-                                    return Err(ParseError::new(
-                                        m.sig.span(),
-                                        "first parameter must be the Context",
-                                    ))
-                                }
-                                Some(ctx_arg) => match ctx_arg {
-                                    syn::FnArg::Receiver(_) => {
-                                        return Err(ParseError::new(
-                                            ctx_arg.span(),
-                                            "second parameter must be the Context",
-                                        ))
-                                    }
-                                    syn::FnArg::Typed(arg) => arg,
-                                },
-                            }
-                        }
-                    };
-                    Ok((m.clone(), ctx_accounts_ident(ctx_arg)?))
-                })
-                .next();
-            r.transpose()
-        })
-        .transpose()?
-        .unwrap_or(None);
-
-    // Parse all methods in the above `impl` block.
-    let methods: Option<Vec<StateIx>> = impl_block
-        .as_ref()
-        .map(|impl_block| {
-            impl_block
-                .items
-                .iter()
-                .filter_map(|item| match item {
-                    syn::ImplItem::Method(m) => match m.sig.ident != CTOR_METHOD_NAME {
-                        false => None,
-                        true => Some(m),
-                    },
-                    _ => None,
-                })
-                .map(|m: &syn::ImplItemMethod| {
-                    let mut args = m
-                        .sig
-                        .inputs
-                        .iter()
-                        .filter_map(|arg| match arg {
-                            syn::FnArg::Receiver(_) => None,
-                            syn::FnArg::Typed(arg) => Some(arg),
-                        })
-                        .map(|raw_arg| {
-                            let docs = docs::parse(&raw_arg.attrs);
-                            let ident = match &*raw_arg.pat {
-                                syn::Pat::Ident(ident) => &ident.ident,
-                                _ => {
-                                    return Err(ParseError::new(
-                                        raw_arg.pat.span(),
-                                        "unexpected type argument",
-                                    ))
-                                }
-                            };
-                            Ok(IxArg {
-                                name: ident.clone(),
-                                docs,
-                                raw_arg: raw_arg.clone(),
-                            })
-                        })
-                        .collect::<ParseResult<Vec<IxArg>>>()?;
-                    // Remove the Anchor accounts argument
-                    let anchor = args.remove(0);
-                    let anchor_ident = ctx_accounts_ident(&anchor.raw_arg)?;
-
-                    Ok(StateIx {
-                        raw_method: m.clone(),
-                        ident: m.sig.ident.clone(),
-                        args,
-                        anchor_ident,
-                        has_receiver: true,
-                    })
-                })
-                .collect::<ParseResult<Vec<_>>>()
-        })
-        .transpose()?;
-
-    // Parse all trait implementations for the above `#[state]` struct.
-    let trait_impls: Option<Vec<StateInterface>> = strct
-        .map(|_strct| {
-            mod_content
-                .iter()
-                .filter_map(|item| match item {
-                    syn::Item::Impl(item_impl) => match &item_impl.trait_ {
-                        None => None,
-                        Some((_, path, _)) => {
-                            let trait_name = path
-                                .segments
-                                .iter()
-                                .next()
-                                .expect("Must have one segment in a path")
-                                .ident
-                                .clone()
-                                .to_string();
-                            Some((item_impl, trait_name))
-                        }
-                    },
-                    _ => None,
-                })
-                .map(|(item_impl, trait_name)| {
-                    let methods = item_impl
-                        .items
-                        .iter()
-                        .filter_map(|item: &syn::ImplItem| match item {
-                            syn::ImplItem::Method(m) => Some(m),
-                            _ => None,
-                        })
-                        .map(|m: &syn::ImplItemMethod| {
-                            match m.sig.inputs.first() {
-                                None => Err(ParseError::new(
-                                    m.sig.inputs.span(),
-                                    "state methods must have a self argument",
-                                )),
-                                Some(_arg) => {
-                                    let mut has_receiver = false;
-                                    let mut args = m
-                                        .sig
-                                        .inputs
-                                        .iter()
-                                        .filter_map(|arg| match arg {
-                                            syn::FnArg::Receiver(_) => {
-                                                has_receiver = true;
-                                                None
-                                            }
-                                            syn::FnArg::Typed(arg) => Some(arg),
-                                        })
-                                        .map(|raw_arg| {
-                                            let docs = docs::parse(&raw_arg.attrs);
-                                            let ident = match &*raw_arg.pat {
-                                                syn::Pat::Ident(ident) => &ident.ident,
-                                                _ => panic!("invalid syntax"),
-                                            };
-                                            IxArg {
-                                                name: ident.clone(),
-                                                docs,
-                                                raw_arg: raw_arg.clone(),
-                                            }
-                                        })
-                                        .collect::<Vec<IxArg>>();
-                                    // Remove the Anchor accounts argument
-                                    let anchor = args.remove(0);
-                                    let anchor_ident = ctx_accounts_ident(&anchor.raw_arg)?;
-
-                                    Ok(StateIx {
-                                        raw_method: m.clone(),
-                                        ident: m.sig.ident.clone(),
-                                        args,
-                                        anchor_ident,
-                                        has_receiver,
-                                    })
-                                }
-                            }
-                        })
-                        .collect::<ParseResult<Vec<StateIx>>>()?;
-                    Ok(StateInterface {
-                        trait_name,
-                        methods,
-                    })
-                })
-                .collect::<ParseResult<Vec<StateInterface>>>()
-        })
-        .transpose()?;
-
-    Ok(strct.map(|(strct, is_zero_copy)| {
-        // Chop off the `#[state]` attribute. It's just a marker.
-        //
-        // TODO: instead of mutating the syntax, we should just implement
-        //       a macro that does nothing.
-        let mut strct = strct.clone();
-        strct.attrs = vec![];
-
-        State {
-            name: strct.ident.to_string(),
-            strct,
-            interfaces: trait_impls,
-            impl_block_and_methods: impl_block.map(|impl_block| (impl_block, methods.unwrap())),
-            ctor_and_anchor,
-            is_zero_copy,
-        }
-    }))
-}

+ 0 - 12
tests/interface/Anchor.toml

@@ -1,12 +0,0 @@
-[provider]
-cluster = "localnet"
-wallet = "~/.config/solana/id.json"
-
-[programs.localnet]
-counter = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
-counter_auth = "Aws2XRVHjNqCUbMmaU245ojT2DBJFYX58KVo2YySEeeP"
-
-[scripts]
-test = "yarn run mocha -t 1000000 tests/"
-
-[features]

+ 0 - 4
tests/interface/Cargo.toml

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

+ 0 - 19
tests/interface/package.json

@@ -1,19 +0,0 @@
-{
-  "name": "interface",
-  "version": "0.26.0",
-  "license": "(MIT OR Apache-2.0)",
-  "homepage": "https://github.com/coral-xyz/anchor#readme",
-  "bugs": {
-    "url": "https://github.com/coral-xyz/anchor/issues"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/coral-xyz/anchor.git"
-  },
-  "engines": {
-    "node": ">=11"
-  },
-  "scripts": {
-    "test": "anchor test"
-  }
-}

+ 0 - 20
tests/interface/programs/counter-auth/Cargo.toml

@@ -1,20 +0,0 @@
-[package]
-name = "counter-auth"
-version = "0.1.0"
-description = "Created with Anchor"
-rust-version = "1.59"
-edition = "2021"
-
-[lib]
-crate-type = ["cdylib", "lib"]
-name = "counter_auth"
-
-[features]
-no-entrypoint = []
-no-idl = []
-cpi = ["no-entrypoint"]
-default = []
-
-[dependencies]
-anchor-lang = { path = "../../../../lang" }
-counter = { path = "../counter", features = ["cpi"] }

+ 0 - 2
tests/interface/programs/counter-auth/Xargo.toml

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

+ 0 - 35
tests/interface/programs/counter-auth/src/lib.rs

@@ -1,35 +0,0 @@
-//! counter-auth is an example of a program *implementing* an external program
-//! interface. Here the `counter::Auth` trait, where we only allow a count
-//! to be incremented if it changes the counter from odd -> even or even -> odd.
-//! Creative, I know. :P.
-
-use anchor_lang::prelude::*;
-use counter::Auth;
-
-declare_id!("Aws2XRVHjNqCUbMmaU245ojT2DBJFYX58KVo2YySEeeP");
-
-#[program]
-pub mod counter_auth {
-    use super::*;
-
-    #[state]
-    pub struct CounterAuth;
-
-    impl<'info> Auth<'info, Empty> for CounterAuth {
-        fn is_authorized(_ctx: Context<Empty>, current: u64, new: u64) -> Result<()> {
-            if current % 2 == 0 {
-                if new % 2 == 0 {
-                    return Err(ProgramError::Custom(15000).into()); // Arbitrary error code.
-                }
-            } else {
-                if new % 2 == 1 {
-                    return Err(ProgramError::Custom(16000).into()); // Arbitrary error code.
-                }
-            }
-            Ok(())
-        }
-    }
-}
-
-#[derive(Accounts)]
-pub struct Empty {}

+ 0 - 19
tests/interface/programs/counter/Cargo.toml

@@ -1,19 +0,0 @@
-[package]
-name = "counter"
-version = "0.1.0"
-description = "Created with Anchor"
-rust-version = "1.59"
-edition = "2021"
-
-[lib]
-crate-type = ["cdylib", "lib"]
-name = "counter"
-
-[features]
-no-entrypoint = []
-no-idl = []
-cpi = ["no-entrypoint"]
-default = []
-
-[dependencies]
-anchor-lang = { path = "../../../../lang" }

+ 0 - 2
tests/interface/programs/counter/Xargo.toml

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

+ 0 - 73
tests/interface/programs/counter/src/lib.rs

@@ -1,73 +0,0 @@
-//! counter is an example program that depends on an external interface
-//! that another program (here counter-auth/src/lib.rs) must implement. This allows
-//! our program to depend on another program, without knowing anything about it
-//! other than that it implements the `Auth` trait.
-//!
-//! Here, we have a counter, where, in order to set the count, the `Auth`
-//! program must first approve the transaction.
-
-use anchor_lang::prelude::*;
-
-declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
-
-#[program]
-pub mod counter {
-    use super::*;
-
-    #[state]
-    pub struct Counter {
-        pub count: u64,
-        pub auth_program: Pubkey,
-    }
-
-    impl Counter {
-        pub fn new(_ctx: Context<Empty>, auth_program: Pubkey) -> Result<Self> {
-            Ok(Self {
-                count: 0,
-                auth_program,
-            })
-        }
-
-        #[access_control(SetCount::accounts(&self, &ctx))]
-        pub fn set_count(&mut self, ctx: Context<SetCount>, new_count: u64) -> Result<()> {
-            // Ask the auth program if we should approve the transaction.
-            let cpi_program = ctx.accounts.auth_program.clone();
-            let cpi_ctx = CpiContext::new(cpi_program, Empty {});
-            auth::is_authorized(cpi_ctx, self.count, new_count)?;
-
-            // Approved, so update.
-            self.count = new_count;
-            Ok(())
-        }
-    }
-}
-
-#[derive(Accounts)]
-pub struct Empty {}
-
-#[derive(Accounts)]
-pub struct SetCount<'info> {
-    auth_program: AccountInfo<'info>,
-}
-
-impl<'info> SetCount<'info> {
-    // Auxiliary account validation requiring program inputs. As a convention,
-    // we separate it from the business logic of the instruction handler itself.
-    pub fn accounts(counter: &Counter, ctx: &Context<SetCount>) -> Result<()> {
-        if ctx.accounts.auth_program.key != &counter.auth_program {
-            return err!(ErrorCode::InvalidAuthProgram);
-        }
-        Ok(())
-    }
-}
-
-#[interface]
-pub trait Auth<'info, T: Accounts<'info>> {
-    fn is_authorized(ctx: Context<T>, current: u64, new: u64) -> Result<()>;
-}
-
-#[error_code]
-pub enum ErrorCode {
-    #[msg("Invalid auth program.")]
-    InvalidAuthProgram,
-}

+ 0 - 46
tests/interface/tests/interface.js

@@ -1,46 +0,0 @@
-const anchor = require("@coral-xyz/anchor");
-const { assert } = require("chai");
-const nativeAssert = require("assert");
-
-describe("interface", () => {
-  // Configure the client to use the local cluster.
-  anchor.setProvider(anchor.AnchorProvider.env());
-
-  const counter = anchor.workspace.Counter;
-  const counterAuth = anchor.workspace.CounterAuth;
-  it("Is initialized!", async () => {
-    await counter.state.rpc.new(counterAuth.programId);
-
-    const stateAccount = await counter.state.fetch();
-    assert.isTrue(stateAccount.count.eq(new anchor.BN(0)));
-    assert.isTrue(stateAccount.authProgram.equals(counterAuth.programId));
-  });
-
-  it("Should fail to go from even to even", async () => {
-    await nativeAssert.rejects(
-      async () => {
-        await counter.state.rpc.setCount(new anchor.BN(4), {
-          accounts: {
-            authProgram: counterAuth.programId,
-          },
-        });
-      },
-      (err) => {
-        if (err.toString().split("custom program error: 0x3a98").length !== 2) {
-          return false;
-        }
-        return true;
-      }
-    );
-  });
-
-  it("Should succeed to go from even to odd", async () => {
-    await counter.state.rpc.setCount(new anchor.BN(3), {
-      accounts: {
-        authProgram: counterAuth.programId,
-      },
-    });
-    const stateAccount = await counter.state.fetch();
-    assert.isTrue(stateAccount.count.eq(new anchor.BN(3)));
-  });
-});

+ 0 - 1
tests/misc/Anchor.toml

@@ -4,7 +4,6 @@ wallet = "~/.config/solana/id.json"
 
 [programs.localnet]
 misc = "3TEqcc8xhrhdspwbvoamUJe2borm4Nr72JxL66k6rgrh"
-misc2 = "HmbTLCmaGvZhKnn1Zfa1JVnp7vkMV4DYVxPLWBVoN65L"
 misc_optional = "FNqz6pqLAwvMSds2FYjR4nKV3moVpPNtvkfGFrqLKrgG"
 idl_doc = "BqmKjZGVa8fqyWuojJzG16zaKSV1GjAisZToNuvEaz6m"
 init_if_needed = "BZoppwWi6jMnydnUBEJzotgEXHwLr3b3NramJgZtWeF2"

+ 0 - 1
tests/misc/programs/misc-optional/Cargo.toml

@@ -18,5 +18,4 @@ default = []
 [dependencies]
 anchor-lang = { path = "../../../../lang", features = ["init-if-needed"] }
 anchor-spl = { path = "../../../../spl" }
-misc2 = { path = "../misc2", features = ["cpi"] }
 spl-associated-token-account = "1.1.1"

+ 0 - 20
tests/misc/programs/misc-optional/src/context.rs

@@ -1,10 +1,8 @@
 use crate::account::*;
-use anchor_lang::accounts::cpi_state::CpiState;
 use anchor_lang::accounts::loader::Loader;
 use anchor_lang::prelude::*;
 use anchor_spl::associated_token::AssociatedToken;
 use anchor_spl::token::{Mint, Token, TokenAccount};
-use misc2::misc2::MyState as Misc2State;
 
 #[derive(Accounts)]
 pub struct TestTokenSeedsInit<'info> {
@@ -120,12 +118,6 @@ pub struct TestPdaMutZeroCopy<'info> {
     pub my_payer: Option<AccountInfo<'info>>,
 }
 
-#[derive(Accounts)]
-pub struct Ctor {}
-
-#[derive(Accounts)]
-pub struct RemainingAccounts {}
-
 #[derive(Accounts)]
 pub struct Initialize<'info> {
     #[account(zero)]
@@ -160,18 +152,6 @@ pub struct TestExecutable<'info> {
     pub program: Option<AccountInfo<'info>>,
 }
 
-#[derive(Accounts)]
-pub struct TestStateCpi<'info> {
-    #[account(signer)]
-    /// CHECK:
-    pub authority: Option<AccountInfo<'info>>,
-    #[account(mut, state = misc2_program)]
-    pub cpi_state: Option<CpiState<'info, Misc2State>>,
-    #[account(executable)]
-    /// CHECK:
-    pub misc2_program: Option<AccountInfo<'info>>,
-}
-
 #[derive(Accounts)]
 pub struct TestClose<'info> {
     #[account(mut, close = sol_dest)]

+ 0 - 35
tests/misc/programs/misc-optional/src/lib.rs

@@ -5,7 +5,6 @@ use account::MAX_SIZE;
 use anchor_lang::prelude::*;
 use context::*;
 use event::*;
-use misc2::Auth;
 
 mod account;
 mod context;
@@ -23,26 +22,6 @@ pub const NO_IDL: u16 = 55;
 pub mod misc_optional {
     use super::*;
 
-    pub const SIZE: u64 = 99;
-
-    #[state(SIZE)]
-    pub struct MyState {
-        pub v: Vec<u8>,
-    }
-
-    impl MyState {
-        pub fn new(_ctx: Context<Ctor>) -> Result<Self> {
-            Ok(Self { v: vec![] })
-        }
-
-        pub fn remaining_accounts(&mut self, ctx: Context<RemainingAccounts>) -> Result<()> {
-            if ctx.remaining_accounts.len() != 1 {
-                return Err(ProgramError::Custom(1).into()); // Arbitrary error.
-            }
-            Ok(())
-        }
-    }
-
     pub fn initialize(ctx: Context<Initialize>, udata: u128, idata: i128) -> Result<()> {
         ctx.accounts.data.as_mut().unwrap().udata = udata;
         ctx.accounts.data.as_mut().unwrap().idata = idata;
@@ -65,20 +44,6 @@ pub mod misc_optional {
         Ok(())
     }
 
-    pub fn test_state_cpi(ctx: Context<TestStateCpi>, data: u64) -> Result<()> {
-        let cpi_program = ctx.accounts.misc2_program.as_ref().unwrap().clone();
-        let cpi_accounts = Auth {
-            authority: ctx.accounts.authority.as_ref().unwrap().clone(),
-        };
-        let ctx = ctx
-            .accounts
-            .cpi_state
-            .as_ref()
-            .unwrap()
-            .context(cpi_program, cpi_accounts);
-        misc2::cpi::state::set_data(ctx, data)
-    }
-
     pub fn test_u16(ctx: Context<TestU16>, data: u16) -> Result<()> {
         ctx.accounts.my_account.as_mut().unwrap().data = data;
         Ok(())

+ 0 - 1
tests/misc/programs/misc/Cargo.toml

@@ -18,5 +18,4 @@ default = []
 [dependencies]
 anchor-lang = { path = "../../../../lang", features = ["init-if-needed"] }
 anchor-spl = { path = "../../../../spl" }
-misc2 = { path = "../misc2", features = ["cpi"] }
 spl-associated-token-account = "1.1.1"

+ 0 - 14
tests/misc/programs/misc/src/context.rs

@@ -1,10 +1,8 @@
 use crate::account::*;
-use anchor_lang::accounts::cpi_state::CpiState;
 use anchor_lang::accounts::loader::Loader;
 use anchor_lang::prelude::*;
 use anchor_spl::associated_token::AssociatedToken;
 use anchor_spl::token::{Mint, Token, TokenAccount};
-use misc2::misc2::MyState as Misc2State;
 
 #[derive(Accounts)]
 pub struct TestTokenSeedsInit<'info> {
@@ -160,18 +158,6 @@ pub struct TestExecutable<'info> {
     pub program: AccountInfo<'info>,
 }
 
-#[derive(Accounts)]
-pub struct TestStateCpi<'info> {
-    #[account(signer)]
-    /// CHECK:
-    pub authority: AccountInfo<'info>,
-    #[account(mut, state = misc2_program)]
-    pub cpi_state: CpiState<'info, Misc2State>,
-    #[account(executable)]
-    /// CHECK:
-    pub misc2_program: AccountInfo<'info>,
-}
-
 #[derive(Accounts)]
 pub struct TestClose<'info> {
     #[account(mut, close = sol_dest)]

+ 0 - 30
tests/misc/programs/misc/src/lib.rs

@@ -5,7 +5,6 @@ use account::MAX_SIZE;
 use anchor_lang::prelude::*;
 use context::*;
 use event::*;
-use misc2::Auth;
 
 mod account;
 mod context;
@@ -27,26 +26,6 @@ pub const NO_IDL: u16 = 55;
 pub mod misc {
     use super::*;
 
-    pub const SIZE: u64 = 99;
-
-    #[state(SIZE)]
-    pub struct MyState {
-        pub v: Vec<u8>,
-    }
-
-    impl MyState {
-        pub fn new(_ctx: Context<Ctor>) -> Result<Self> {
-            Ok(Self { v: vec![] })
-        }
-
-        pub fn remaining_accounts(&mut self, ctx: Context<RemainingAccounts>) -> Result<()> {
-            if ctx.remaining_accounts.len() != 1 {
-                return Err(ProgramError::Custom(1).into()); // Arbitrary error.
-            }
-            Ok(())
-        }
-    }
-
     pub fn initialize(ctx: Context<Initialize>, udata: u128, idata: i128) -> Result<()> {
         ctx.accounts.data.udata = udata;
         ctx.accounts.data.idata = idata;
@@ -69,15 +48,6 @@ pub mod misc {
         Ok(())
     }
 
-    pub fn test_state_cpi(ctx: Context<TestStateCpi>, data: u64) -> Result<()> {
-        let cpi_program = ctx.accounts.misc2_program.clone();
-        let cpi_accounts = Auth {
-            authority: ctx.accounts.authority.clone(),
-        };
-        let ctx = ctx.accounts.cpi_state.context(cpi_program, cpi_accounts);
-        misc2::cpi::state::set_data(ctx, data)
-    }
-
     pub fn test_u16(ctx: Context<TestU16>, data: u16) -> Result<()> {
         ctx.accounts.my_account.data = data;
         Ok(())

+ 0 - 19
tests/misc/programs/misc2/Cargo.toml

@@ -1,19 +0,0 @@
-[package]
-name = "misc2"
-version = "0.1.0"
-description = "Created with Anchor"
-rust-version = "1.59"
-edition = "2021"
-
-[lib]
-crate-type = ["cdylib", "lib"]
-name = "misc2"
-
-[features]
-no-entrypoint = []
-no-idl = []
-cpi = ["no-entrypoint"]
-default = []
-
-[dependencies]
-anchor-lang = { path = "../../../../lang" }

+ 0 - 2
tests/misc/programs/misc2/Xargo.toml

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

+ 0 - 38
tests/misc/programs/misc2/src/lib.rs

@@ -1,38 +0,0 @@
-use anchor_lang::prelude::*;
-
-declare_id!("HmbTLCmaGvZhKnn1Zfa1JVnp7vkMV4DYVxPLWBVoN65L");
-
-#[program]
-pub mod misc2 {
-    use super::*;
-
-    #[state]
-    pub struct MyState {
-        pub data: u64,
-        pub auth: Pubkey,
-    }
-
-    impl MyState {
-        pub fn new(ctx: Context<Auth>) -> Result<Self> {
-            Ok(Self {
-                data: 0,
-                auth: *ctx.accounts.authority.key,
-            })
-        }
-
-        pub fn set_data(&mut self, ctx: Context<Auth>, data: u64) -> Result<()> {
-            if self.auth != *ctx.accounts.authority.key {
-                return Err(ProgramError::Custom(1234).into()); // Arbitrary error code.
-            }
-            self.data = data;
-            Ok(())
-        }
-    }
-}
-
-#[derive(Accounts)]
-pub struct Auth<'info> {
-    #[account(signer)]
-    /// CHECK:
-    pub authority: AccountInfo<'info>,
-}

+ 1 - 72
tests/misc/tests/misc/misc.ts

@@ -1,18 +1,9 @@
 import * as anchor from "@coral-xyz/anchor";
-import {
-  Program,
-  BN,
-  IdlAccounts,
-  AnchorError,
-  Wallet,
-  IdlTypes,
-  IdlEvents,
-} from "@coral-xyz/anchor";
+import { Program, BN, AnchorError, Wallet, IdlEvents } from "@coral-xyz/anchor";
 import {
   PublicKey,
   Keypair,
   SystemProgram,
-  SYSVAR_RENT_PUBKEY,
   Message,
   VersionedTransaction,
 } from "@solana/web3.js";
@@ -23,7 +14,6 @@ import {
 } from "@solana/spl-token";
 import { Misc } from "../../target/types/misc";
 import { MiscOptional } from "../../target/types/misc_optional";
-import { Misc2 } from "../../target/types/misc2";
 
 const utf8 = anchor.utils.bytes.utf8;
 const { assert, expect } = require("chai");
@@ -38,31 +28,6 @@ const miscTest = (
     const provider = anchor.AnchorProvider.env();
     const wallet = provider.wallet as Wallet;
     anchor.setProvider(provider);
-    const misc2Program = anchor.workspace.Misc2 as Program<Misc2>;
-
-    it("Can allocate extra space for a state constructor", async () => {
-      // @ts-expect-error
-      const tx = await program.state.rpc.new();
-      const addr = await program.state.address();
-      const state = await program.state.fetch();
-      const accountInfo = await program.provider.connection.getAccountInfo(
-        addr
-      );
-      assert.isTrue(state.v.equals(Buffer.from([])));
-      assert.lengthOf(accountInfo.data, 99);
-    });
-
-    it("Can use remaining accounts for a state instruction", async () => {
-      await program.state.rpc.remainingAccounts({
-        remainingAccounts: [
-          {
-            pubkey: misc2Program.programId,
-            isWritable: false,
-            isSigner: false,
-          },
-        ],
-      });
-    });
 
     const data = anchor.web3.Keypair.generate();
 
@@ -148,42 +113,6 @@ const miscTest = (
       );
     });
 
-    it("Can CPI to state instructions", async () => {
-      const oldData = new anchor.BN(0);
-      try {
-        await misc2Program.state.fetch();
-        // if state account already exists, reset data to oldData.
-        await program.rpc.testStateCpi(oldData, {
-          accounts: {
-            authority: provider.wallet.publicKey,
-            cpiState: await misc2Program.state.address(),
-            misc2Program: misc2Program.programId,
-          },
-        });
-      } catch (e) {
-        // initialize if it doesn't exist
-        await misc2Program.state.rpc.new({
-          accounts: {
-            authority: provider.wallet.publicKey,
-          },
-        });
-      }
-      let stateAccount = await misc2Program.state.fetch();
-      assert.isTrue(stateAccount.data.eq(oldData));
-      assert.isTrue(stateAccount.auth.equals(provider.wallet.publicKey));
-      const newData = new anchor.BN(2134);
-      await program.rpc.testStateCpi(newData, {
-        accounts: {
-          authority: provider.wallet.publicKey,
-          cpiState: await misc2Program.state.address(),
-          misc2Program: misc2Program.programId,
-        },
-      });
-      stateAccount = await misc2Program.state.fetch();
-      assert.isTrue(stateAccount.data.eq(newData));
-      assert.isTrue(stateAccount.auth.equals(provider.wallet.publicKey));
-    });
-
     it("Can retrieve events when simulating a transaction", async () => {
       const resp = await program.methods.testSimulate(44).simulate();
       const expectedRaw = [

+ 1 - 1
tests/zero-copy/programs/zero-cpi/src/lib.rs

@@ -16,7 +16,7 @@ pub mod zero_cpi {
             foo: ctx.accounts.foo.to_account_info(),
         };
         let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
-        zero_copy::cpi::update_bar(cpi_ctx, data);
+        zero_copy::cpi::update_bar(cpi_ctx, data)?;
         Ok(())
     }
 }

+ 0 - 10
ts/packages/anchor/src/coder/borsh/index.ts

@@ -2,14 +2,12 @@ import { Idl } from "../../idl.js";
 import { BorshInstructionCoder } from "./instruction.js";
 import { BorshAccountsCoder } from "./accounts.js";
 import { BorshEventCoder } from "./event.js";
-import { BorshStateCoder } from "./state.js";
 import { BorshTypesCoder } from "./types.js";
 import { Coder } from "../index.js";
 
 export { BorshInstructionCoder } from "./instruction.js";
 export { BorshAccountsCoder, ACCOUNT_DISCRIMINATOR_SIZE } from "./accounts.js";
 export { BorshEventCoder, eventDiscriminator } from "./event.js";
-export { BorshStateCoder, stateDiscriminator } from "./state.js";
 
 /**
  * BorshCoder is the default Coder for Anchor programs implementing the
@@ -28,11 +26,6 @@ export class BorshCoder<A extends string = string, T extends string = string>
    */
   readonly accounts: BorshAccountsCoder<A>;
 
-  /**
-   * Coder for state structs.
-   */
-  readonly state: BorshStateCoder;
-
   /**
    * Coder for events.
    */
@@ -47,9 +40,6 @@ export class BorshCoder<A extends string = string, T extends string = string>
     this.instruction = new BorshInstructionCoder(idl);
     this.accounts = new BorshAccountsCoder(idl);
     this.events = new BorshEventCoder(idl);
-    if (idl.state) {
-      this.state = new BorshStateCoder(idl);
-    }
     this.types = new BorshTypesCoder(idl);
   }
 }

+ 10 - 46
ts/packages/anchor/src/coder/borsh/instruction.ts

@@ -9,7 +9,6 @@ import { AccountMeta, PublicKey } from "@solana/web3.js";
 import {
   Idl,
   IdlField,
-  IdlStateMethod,
   IdlType,
   IdlTypeDef,
   IdlAccount,
@@ -23,10 +22,6 @@ import {
 import { IdlCoder } from "./idl.js";
 import { InstructionCoder } from "../index.js";
 
-/**
- * Namespace for state method function signatures.
- */
-export const SIGHASH_STATE_NAMESPACE = "state";
 /**
  * Namespace for global instruction function signatures (i.e. functions
  * that aren't namespaced by the state or any of its trait implementations).
@@ -55,16 +50,6 @@ export class BorshInstructionCoder implements InstructionCoder {
       });
     });
 
-    if (idl.state) {
-      idl.state.methods.map((ix) => {
-        const sh = sighash(SIGHASH_STATE_NAMESPACE, ix.name);
-        sighashLayouts.set(bs58.encode(sh), {
-          layout: this.ixLayout.get(ix.name) as Layout,
-          name: ix.name,
-        });
-      });
-    }
-
     this.sighashLayouts = sighashLayouts;
   }
 
@@ -75,13 +60,6 @@ export class BorshInstructionCoder implements InstructionCoder {
     return this._encode(SIGHASH_GLOBAL_NAMESPACE, ixName, ix);
   }
 
-  /**
-   * Encodes a program state instruction.
-   */
-  public encodeState(ixName: string, ix: any): Buffer {
-    return this._encode(SIGHASH_STATE_NAMESPACE, ixName, ix);
-  }
-
   private _encode(nameSpace: string, ixName: string, ix: any): Buffer {
     const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer.
     const methodName = camelCase(ixName);
@@ -95,31 +73,17 @@ export class BorshInstructionCoder implements InstructionCoder {
   }
 
   private static parseIxLayout(idl: Idl): Map<string, Layout> {
-    const stateMethods = idl.state ? idl.state.methods : [];
-
-    const ixLayouts = stateMethods
-      .map((m: IdlStateMethod): [string, Layout<unknown>] => {
-        let fieldLayouts = m.args.map((arg: IdlField) => {
-          return IdlCoder.fieldLayout(
-            arg,
-            Array.from([...(idl.accounts ?? []), ...(idl.types ?? [])])
-          );
-        });
-        const name = camelCase(m.name);
-        return [name, borsh.struct(fieldLayouts, name)];
-      })
-      .concat(
-        idl.instructions.map((ix) => {
-          let fieldLayouts = ix.args.map((arg: IdlField) =>
-            IdlCoder.fieldLayout(
-              arg,
-              Array.from([...(idl.accounts ?? []), ...(idl.types ?? [])])
-            )
-          );
-          const name = camelCase(ix.name);
-          return [name, borsh.struct(fieldLayouts, name)];
-        })
+    const ixLayouts = idl.instructions.map((ix): [string, Layout<unknown>] => {
+      let fieldLayouts = ix.args.map((arg: IdlField) =>
+        IdlCoder.fieldLayout(
+          arg,
+          Array.from([...(idl.accounts ?? []), ...(idl.types ?? [])])
+        )
       );
+      const name = camelCase(ix.name);
+      return [name, borsh.struct(fieldLayouts, name)];
+    });
+
     return new Map(ixLayouts);
   }
 

+ 0 - 39
ts/packages/anchor/src/coder/borsh/state.ts

@@ -1,39 +0,0 @@
-import { Buffer } from "buffer";
-import { Layout } from "buffer-layout";
-import { sha256 } from "js-sha256";
-import { Idl } from "../../idl.js";
-import { IdlCoder } from "./idl.js";
-import * as features from "../../utils/features.js";
-
-export class BorshStateCoder {
-  private layout: Layout;
-
-  public constructor(idl: Idl) {
-    if (idl.state === undefined) {
-      throw new Error("Idl state not defined.");
-    }
-    this.layout = IdlCoder.typeDefLayout(idl.state.struct, idl.types);
-  }
-
-  public async encode<T = any>(name: string, account: T): Promise<Buffer> {
-    const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer.
-    const len = this.layout.encode(account, buffer);
-
-    const disc = await stateDiscriminator(name);
-    const accData = buffer.slice(0, len);
-
-    return Buffer.concat([disc, accData]);
-  }
-
-  public decode<T = any>(ix: Buffer): T {
-    // Chop off discriminator.
-    const data = ix.slice(8);
-    return this.layout.decode(data);
-  }
-}
-
-// Calculates unique 8 byte discriminator prepended to all anchor state accounts.
-export async function stateDiscriminator(name: string): Promise<Buffer> {
-  let ns = features.isSet("anchor-deprecated-state") ? "account" : "state";
-  return Buffer.from(sha256.digest(`${ns}:${name}`)).slice(0, 8);
-}

+ 0 - 6
ts/packages/anchor/src/coder/index.ts

@@ -18,11 +18,6 @@ export interface Coder<A extends string = string, T extends string = string> {
    */
   readonly accounts: AccountsCoder<A>;
 
-  /**
-   * Coder for state structs.
-   */
-  readonly state: StateCoder;
-
   /**
    * Coder for events.
    */
@@ -49,7 +44,6 @@ export interface AccountsCoder<A extends string = string> {
 
 export interface InstructionCoder {
   encode(ixName: string, ix: any): Buffer;
-  encodeState(ixName: string, ix: any): Buffer;
 }
 
 export interface EventCoder {

+ 0 - 3
ts/packages/anchor/src/coder/system/index.ts

@@ -1,7 +1,6 @@
 import { Idl } from "../../idl.js";
 import { Coder } from "../index.js";
 import { SystemInstructionCoder } from "./instruction.js";
-import { SystemStateCoder } from "./state.js";
 import { SystemAccountsCoder } from "./accounts.js";
 import { SystemEventsCoder } from "./events.js";
 import { SystemTypesCoder } from "./types.js";
@@ -12,7 +11,6 @@ import { SystemTypesCoder } from "./types.js";
 export class SystemCoder implements Coder {
   readonly instruction: SystemInstructionCoder;
   readonly accounts: SystemAccountsCoder;
-  readonly state: SystemStateCoder;
   readonly events: SystemEventsCoder;
   readonly types: SystemTypesCoder;
 
@@ -20,7 +18,6 @@ export class SystemCoder implements Coder {
     this.instruction = new SystemInstructionCoder(idl);
     this.accounts = new SystemAccountsCoder(idl);
     this.events = new SystemEventsCoder(idl);
-    this.state = new SystemStateCoder(idl);
     this.types = new SystemTypesCoder(idl);
   }
 }

+ 0 - 14
ts/packages/anchor/src/coder/system/state.ts

@@ -1,14 +0,0 @@
-import { StateCoder } from "../index.js";
-import { Idl } from "../../idl";
-
-export class SystemStateCoder implements StateCoder {
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
-  constructor(_idl: Idl) {}
-
-  encode<T = any>(_name: string, _account: T): Promise<Buffer> {
-    throw new Error("System does not have state");
-  }
-  decode<T = any>(_ix: Buffer): T {
-    throw new Error("System does not have state");
-  }
-}

+ 4 - 10
ts/packages/anchor/src/error.ts

@@ -368,9 +368,6 @@ export const LangErrorCode = {
   AccountReallocExceedsLimit: 3016,
   AccountDuplicateReallocs: 3017,
 
-  // State.
-  StateInvalidAddress: 4000,
-
   // Miscellaneous
   DeclaredProgramIdMismatch: 4100,
 
@@ -419,7 +416,10 @@ export const LangErrorMessage = new Map([
   ],
   [LangErrorCode.ConstraintSeeds, "A seeds constraint was violated"],
   [LangErrorCode.ConstraintExecutable, "An executable constraint was violated"],
-  [LangErrorCode.ConstraintState, "A state constraint was violated"],
+  [
+    LangErrorCode.ConstraintState,
+    "Deprecated Error, feel free to replace with something else",
+  ],
   [LangErrorCode.ConstraintAssociated, "An associated constraint was violated"],
   [
     LangErrorCode.ConstraintAssociatedInit,
@@ -519,12 +519,6 @@ export const LangErrorMessage = new Map([
     "The account was duplicated for more than one reallocation",
   ],
 
-  // State.
-  [
-    LangErrorCode.StateInvalidAddress,
-    "The given state account does not have the correct address",
-  ],
-
   // Miscellaneous
   [
     LangErrorCode.DeclaredProgramIdMismatch,

+ 0 - 6
ts/packages/anchor/src/idl.ts

@@ -7,7 +7,6 @@ export type Idl = {
   name: string;
   docs?: string[];
   instructions: IdlInstruction[];
-  state?: IdlState;
   accounts?: IdlAccountDef[];
   types?: IdlTypeDef[];
   events?: IdlEvent[];
@@ -43,11 +42,6 @@ export type IdlInstruction = {
   returns?: IdlType;
 };
 
-export type IdlState = {
-  struct: IdlTypeDef;
-  methods: IdlStateMethod[];
-};
-
 export type IdlStateMethod = IdlInstruction;
 
 export type IdlAccountItem = IdlAccount | IdlAccounts;

+ 8 - 25
ts/packages/anchor/src/program/index.ts

@@ -8,7 +8,6 @@ import NamespaceFactory, {
   InstructionNamespace,
   TransactionNamespace,
   AccountNamespace,
-  StateClient,
   SimulateNamespace,
   MethodsNamespace,
   ViewNamespace,
@@ -207,13 +206,6 @@ export class Program<IDL extends Idl = Idl> {
    */
   readonly simulate: SimulateNamespace<IDL>;
 
-  /**
-   * A client for the program state. Similar to the base [[Program]] client,
-   * one can use this to send transactions and read accounts for the state
-   * abstraction.
-   */
-  readonly state?: StateClient<IDL>;
-
   /**
    * The namespace provides a builder API for all APIs on the program.
    * This is an alternative to using namespace the other namespaces..
@@ -291,29 +283,20 @@ export class Program<IDL extends Idl = Idl> {
     this._events = new EventManager(this._programId, provider, this._coder);
 
     // Dynamic namespaces.
-    const [
-      rpc,
-      instruction,
-      transaction,
-      account,
-      simulate,
-      methods,
-      state,
-      views,
-    ] = NamespaceFactory.build(
-      idl,
-      this._coder,
-      programId,
-      provider,
-      getCustomResolver ?? (() => undefined)
-    );
+    const [rpc, instruction, transaction, account, simulate, methods, views] =
+      NamespaceFactory.build(
+        idl,
+        this._coder,
+        programId,
+        provider,
+        getCustomResolver ?? (() => undefined)
+      );
     this.rpc = rpc;
     this.instruction = instruction;
     this.transaction = transaction;
     this.account = account;
     this.simulate = simulate;
     this.methods = methods;
-    this.state = state;
     this.views = views;
   }
 

+ 0 - 6
ts/packages/anchor/src/program/namespace/index.ts

@@ -3,7 +3,6 @@ import { PublicKey } from "@solana/web3.js";
 import { Coder } from "../../coder/index.js";
 import Provider from "../../provider.js";
 import { Idl, IdlInstruction } from "../../idl.js";
-import StateFactory, { StateClient } from "./state.js";
 import InstructionFactory, { InstructionNamespace } from "./instruction.js";
 import TransactionFactory, { TransactionNamespace } from "./transaction.js";
 import RpcFactory, { RpcNamespace } from "./rpc.js";
@@ -15,7 +14,6 @@ import ViewFactory, { ViewNamespace } from "./views";
 import { CustomAccountResolver } from "../accounts-resolver.js";
 
 // Re-exports.
-export { StateClient } from "./state.js";
 export { InstructionNamespace, InstructionFn } from "./instruction.js";
 export { TransactionNamespace, TransactionFn } from "./transaction.js";
 export { RpcNamespace, RpcFn } from "./rpc.js";
@@ -44,7 +42,6 @@ export default class NamespaceFactory {
     AccountNamespace<IDL>,
     SimulateNamespace<IDL>,
     MethodsNamespace<IDL>,
-    StateClient<IDL> | undefined,
     ViewNamespace<IDL> | undefined
   ] {
     const rpc: RpcNamespace = {};
@@ -60,8 +57,6 @@ export default class NamespaceFactory {
       ? AccountFactory.build(idl, coder, programId, provider)
       : ({} as AccountNamespace<IDL>);
 
-    const state = StateFactory.build(idl, coder, programId, provider);
-
     idl.instructions.forEach((idlIx) => {
       const ixItem = InstructionFactory.build<IDL, typeof idlIx>(
         idlIx,
@@ -112,7 +107,6 @@ export default class NamespaceFactory {
       account,
       simulate as SimulateNamespace<IDL>,
       methods as MethodsNamespace<IDL>,
-      state,
       view as ViewNamespace<IDL>,
     ];
   }

+ 0 - 286
ts/packages/anchor/src/program/namespace/state.ts

@@ -1,286 +0,0 @@
-import EventEmitter from "eventemitter3";
-import camelCase from "camelcase";
-import {
-  PublicKey,
-  SystemProgram,
-  Commitment,
-  AccountMeta,
-} from "@solana/web3.js";
-import Provider, { getProvider } from "../../provider.js";
-import { Idl, IdlInstruction, IdlStateMethod, IdlTypeDef } from "../../idl.js";
-import { BorshCoder, Coder, stateDiscriminator } from "../../coder/index.js";
-import {
-  RpcNamespace,
-  InstructionNamespace,
-  TransactionNamespace,
-} from "./index.js";
-import { Subscription, validateAccounts, parseIdlErrors } from "../common.js";
-import {
-  findProgramAddressSync,
-  createWithSeedSync,
-} from "../../utils/pubkey.js";
-import { Accounts } from "../context.js";
-import InstructionNamespaceFactory from "./instruction.js";
-import RpcNamespaceFactory from "./rpc.js";
-import TransactionNamespaceFactory from "./transaction.js";
-import { IdlTypes, TypeDef } from "./types.js";
-
-export default class StateFactory {
-  public static build<IDL extends Idl>(
-    idl: IDL,
-    coder: Coder,
-    programId: PublicKey,
-    provider?: Provider
-  ): StateClient<IDL> | undefined {
-    if (idl.state === undefined) {
-      return undefined;
-    }
-    return new StateClient(idl, programId, provider, coder);
-  }
-}
-
-type NullableMethods<IDL extends Idl> = IDL["state"] extends undefined
-  ? IdlInstruction[]
-  : NonNullable<IDL["state"]>["methods"];
-
-/**
- * A client for the program state. Similar to the base [[Program]] client,
- * one can use this to send transactions and read accounts for the state
- * abstraction.
- */
-export class StateClient<IDL extends Idl> {
-  /**
-   * [[RpcNamespace]] for all state methods.
-   */
-  readonly rpc: RpcNamespace<IDL, NullableMethods<IDL>[number]>;
-
-  /**
-   * [[InstructionNamespace]] for all state methods.
-   */
-  readonly instruction: InstructionNamespace<IDL, NullableMethods<IDL>[number]>;
-
-  /**
-   * [[TransactionNamespace]] for all state methods.
-   */
-  readonly transaction: TransactionNamespace<IDL, NullableMethods<IDL>[number]>;
-
-  /**
-   * Returns the program ID owning the state.
-   */
-  get programId(): PublicKey {
-    return this._programId;
-  }
-  private _programId: PublicKey;
-
-  private _address: PublicKey;
-  private _coder: Coder;
-  private _idl: IDL;
-  private _sub: Subscription | null;
-
-  constructor(
-    idl: IDL,
-    programId: PublicKey,
-    /**
-     * Returns the client's wallet and network provider.
-     */
-    public readonly provider: Provider = getProvider(),
-    /**
-     * Returns the coder.
-     */
-    public readonly coder: Coder = new BorshCoder(idl)
-  ) {
-    this._idl = idl;
-    this._programId = programId;
-    this._address = programStateAddress(programId);
-    this._sub = null;
-
-    // Build namespaces.
-    const [instruction, transaction, rpc] = ((): [
-      InstructionNamespace<IDL, NullableMethods<IDL>[number]>,
-      TransactionNamespace<IDL, NullableMethods<IDL>[number]>,
-      RpcNamespace<IDL, NullableMethods<IDL>[number]>
-    ] => {
-      let instruction: InstructionNamespace = {};
-      let transaction: TransactionNamespace = {};
-      let rpc: RpcNamespace = {};
-
-      idl.state?.methods.forEach(
-        <I extends NullableMethods<IDL>[number]>(m: I) => {
-          // Build instruction method.
-          const ixItem = InstructionNamespaceFactory.build<IDL, I>(
-            m,
-            (ixName, ix) => coder.instruction.encodeState(ixName, ix),
-            programId
-          );
-          ixItem["accounts"] = (accounts) => {
-            const keys = stateInstructionKeys(programId, provider, m, accounts);
-            return keys.concat(
-              InstructionNamespaceFactory.accountsArray(
-                accounts,
-                m.accounts,
-                programId,
-                m.name
-              )
-            );
-          };
-          // Build transaction method.
-          const txItem = TransactionNamespaceFactory.build(m, ixItem);
-          // Build RPC method.
-          const rpcItem = RpcNamespaceFactory.build(
-            m,
-            txItem,
-            parseIdlErrors(idl),
-            provider
-          );
-
-          // Attach them all to their respective namespaces.
-          const name = camelCase(m.name);
-          instruction[name] = ixItem;
-          transaction[name] = txItem;
-          rpc[name] = rpcItem;
-        }
-      );
-
-      return [
-        instruction as InstructionNamespace<IDL, NullableMethods<IDL>[number]>,
-        transaction as TransactionNamespace<IDL, NullableMethods<IDL>[number]>,
-        rpc as RpcNamespace<IDL, NullableMethods<IDL>[number]>,
-      ];
-    })();
-    this.instruction = instruction;
-    this.transaction = transaction;
-    this.rpc = rpc;
-  }
-
-  /**
-   * Returns the deserialized state account.
-   */
-  async fetch(): Promise<
-    TypeDef<
-      IDL["state"] extends undefined
-        ? IdlTypeDef
-        : NonNullable<IDL["state"]>["struct"],
-      IdlTypes<IDL>
-    >
-  > {
-    const addr = this.address();
-    const accountInfo = await this.provider.connection.getAccountInfo(addr);
-    if (accountInfo === null) {
-      throw new Error(`Account does not exist ${addr.toString()}`);
-    }
-    // Assert the account discriminator is correct.
-    const state = this._idl.state;
-    if (!state) {
-      throw new Error("State is not specified in IDL.");
-    }
-    const expectedDiscriminator = await stateDiscriminator(state.struct.name);
-    if (expectedDiscriminator.compare(accountInfo.data.slice(0, 8))) {
-      throw new Error("Invalid account discriminator");
-    }
-    return this.coder.state.decode(accountInfo.data);
-  }
-
-  /**
-   * Returns the state address.
-   */
-  address(): PublicKey {
-    return this._address;
-  }
-
-  /**
-   * Returns an `EventEmitter` with a `"change"` event that's fired whenever
-   * the state account cahnges.
-   */
-  subscribe(commitment?: Commitment): EventEmitter {
-    if (this._sub !== null) {
-      return this._sub.ee;
-    }
-    const ee = new EventEmitter();
-
-    const listener = this.provider.connection.onAccountChange(
-      this.address(),
-      (acc) => {
-        const account = this.coder.state.decode(acc.data);
-        ee.emit("change", account);
-      },
-      commitment
-    );
-
-    this._sub = {
-      ee,
-      listener,
-    };
-
-    return ee;
-  }
-
-  /**
-   * Unsubscribes to state changes.
-   */
-  unsubscribe() {
-    if (this._sub !== null) {
-      this.provider.connection
-        .removeAccountChangeListener(this._sub.listener)
-        .then(async () => {
-          this._sub = null;
-        })
-        .catch(console.error);
-    }
-  }
-}
-
-// Calculates the deterministic address of the program's "state" account.
-function programStateAddress(programId: PublicKey): PublicKey {
-  let [registrySigner] = findProgramAddressSync([], programId);
-  return createWithSeedSync(registrySigner, "unversioned", programId);
-}
-
-// Returns the common keys that are prepended to all instructions targeting
-// the "state" of a program.
-function stateInstructionKeys<M extends IdlStateMethod>(
-  programId: PublicKey,
-  provider: Provider,
-  m: M,
-  accounts: Accounts<M["accounts"][number]>
-): AccountMeta[] {
-  if (m.name === "new") {
-    // Ctor `new` method.
-    const [programSigner] = findProgramAddressSync([], programId);
-    // @ts-expect-error
-    if (provider.wallet === undefined) {
-      throw new Error(
-        "This function requires the Provider interface implementor to have a 'wallet' field."
-      );
-    }
-    return [
-      {
-        // @ts-expect-error
-        pubkey: provider.wallet.publicKey,
-        isWritable: false,
-        isSigner: true,
-      },
-      {
-        pubkey: programStateAddress(programId),
-        isWritable: true,
-        isSigner: false,
-      },
-      { pubkey: programSigner, isWritable: false, isSigner: false },
-      {
-        pubkey: SystemProgram.programId,
-        isWritable: false,
-        isSigner: false,
-      },
-
-      { pubkey: programId, isWritable: false, isSigner: false },
-    ];
-  } else {
-    validateAccounts(m.accounts, accounts);
-    return [
-      {
-        pubkey: programStateAddress(programId),
-        isWritable: true,
-        isSigner: false,
-      },
-    ];
-  }
-}