ameliatastic / seahorse-lang

Write Anchor-compatible Solana programs in Python
Apache License 2.0
320 stars 46 forks source link

Make system clock account immutable #45

Closed mcintyre94 closed 1 year ago

mcintyre94 commented 1 year ago

This was first flagged on Discord: https://discordapp.com/channels/1005658120548270224/1006027519952171028/1036610124925632542

The clock account was being generated as mutable:

  #[account(mut)]
  pub clock: Sysvar<'info, Clock>,

This meant that when you run the instruction and pass in the CLOCK_SYSVAR public key, it would fail that constraint and error

This PR fixes it by:

Full example test case:

# programs_py/clock.py
# seahorse_clock
# Built with Seahorse v0.2.2

from seahorse.prelude import *

declare_id('Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS')

@instruction
def hello(c: Clock):
    ts = c.unix_timestamp()
    print(ts)
// tests/seahorse-clock.ts
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { SeahorseClock } from "../target/types/seahorse_clock";
import { SYSVAR_CLOCK_PUBKEY } from "@solana/web3.js"

describe("seahorse_clock", () => {
  // Configure the client to use the local cluster.
  const anchorProvider = anchor.AnchorProvider.env()
  anchor.setProvider(anchorProvider);

  const program = anchor.workspace.SeahorseClock as Program<SeahorseClock>;

  it("Is initialized!", async () => {
    // Add your test here.
    const tx = await program.methods
      .hello()
      .accountsStrict({
        c: SYSVAR_CLOCK_PUBKEY,
      })
      .rpc();
    console.log("Your transaction signature", tx);
  });
});

On current main the test will fail with:

 1) seahorse_clock
       Is initialized!:
     Error: AnchorError caused by account: c. Error Code: ConstraintMut. Error Number: 2000. Error Message: A mut constraint was violated.
      at Function.parse (node_modules/@project-serum/anchor/src/error.ts:167:14)
      at translateError (node_modules/@project-serum/anchor/src/error.ts:276:35)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@project-serum/anchor/src/program/namespace/rpc.ts:35:29)
      at processTicksAndRejections (node:internal/process/task_queues:95:5)

With this PR the test passes

ameliatastic commented 1 year ago

Lifesaver, I had completely forgotten about this bug (why didn't I add it to the board? 😅)