diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 924c01885e..d1b4fb1960 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -276,6 +276,8 @@ jobs: path: tests/cfo - cmd: cd tests/auction-house && yarn && anchor test path: tests/auction-house + - cmd: cd tests/floats && yarn && anchor test + path: tests/floats steps: - uses: actions/checkout@v2 - uses: ./.github/actions/setup/ diff --git a/CHANGELOG.md b/CHANGELOG.md index fd99ac2032..7ded05a60b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ incremented for features. ### Features * lang: add check that declared id == program id ([#1451](https://github.com/project-serum/anchor/pull/1451)) +* ts: Added float types support ([#1425](https://github.com/project-serum/anchor/pull/1425)). ### Fixes diff --git a/lang/syn/src/idl/mod.rs b/lang/syn/src/idl/mod.rs index 9482d36782..f3fb1ac685 100644 --- a/lang/syn/src/idl/mod.rs +++ b/lang/syn/src/idl/mod.rs @@ -174,8 +174,10 @@ pub enum IdlType { I16, U32, I32, + F32, U64, I64, + F64, U128, I128, Bytes, @@ -213,8 +215,10 @@ impl std::str::FromStr for IdlType { "i16" => IdlType::I16, "u32" => IdlType::U32, "i32" => IdlType::I32, + "f32" => IdlType::F32, "u64" => IdlType::U64, "i64" => IdlType::I64, + "f64" => IdlType::F64, "u128" => IdlType::U128, "i128" => IdlType::I128, "Vec" => IdlType::Bytes, diff --git a/tests/floats/Anchor.toml b/tests/floats/Anchor.toml new file mode 100644 index 0000000000..7fcee42ab1 --- /dev/null +++ b/tests/floats/Anchor.toml @@ -0,0 +1,12 @@ +[programs.localnet] +floats = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" + +[registry] +url = "https://anchor.projectserum.com" + +[provider] +cluster = "localnet" +wallet = "~/.config/solana/id.json" + +[scripts] +test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/tests/floats/Cargo.toml b/tests/floats/Cargo.toml new file mode 100644 index 0000000000..a60de986d3 --- /dev/null +++ b/tests/floats/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = [ + "programs/*" +] diff --git a/tests/floats/migrations/deploy.ts b/tests/floats/migrations/deploy.ts new file mode 100644 index 0000000000..5e3df0dc30 --- /dev/null +++ b/tests/floats/migrations/deploy.ts @@ -0,0 +1,12 @@ +// Migrations are an early feature. Currently, they're nothing more than this +// single deploy script that's invoked from the CLI, injecting a provider +// configured from the workspace's Anchor.toml. + +const anchor = require("@project-serum/anchor"); + +module.exports = async function (provider) { + // Configure client to use the provider. + anchor.setProvider(provider); + + // Add your deploy script here. +}; diff --git a/tests/floats/package.json b/tests/floats/package.json new file mode 100644 index 0000000000..ddda9fe210 --- /dev/null +++ b/tests/floats/package.json @@ -0,0 +1,19 @@ +{ + "name": "floats", + "version": "0.21.0", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/project-serum/anchor#readme", + "bugs": { + "url": "https://github.com/project-serum/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/project-serum/anchor.git" + }, + "engines": { + "node": ">=11" + }, + "scripts": { + "test": "anchor test" + } + } diff --git a/tests/floats/programs/floats/Cargo.toml b/tests/floats/programs/floats/Cargo.toml new file mode 100644 index 0000000000..c9a4a2b4ab --- /dev/null +++ b/tests/floats/programs/floats/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "floats" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "floats" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +anchor-lang = { path = "../../../../lang" } diff --git a/tests/floats/programs/floats/Xargo.toml b/tests/floats/programs/floats/Xargo.toml new file mode 100644 index 0000000000..475fb71ed1 --- /dev/null +++ b/tests/floats/programs/floats/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/tests/floats/programs/floats/src/lib.rs b/tests/floats/programs/floats/src/lib.rs new file mode 100644 index 0000000000..d9e85fa7a4 --- /dev/null +++ b/tests/floats/programs/floats/src/lib.rs @@ -0,0 +1,51 @@ +use anchor_lang::prelude::*; + +declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); + +#[program] +pub mod floats { + use super::*; + + pub fn create(ctx: Context, data_f32: f32, data_f64: f64) -> ProgramResult { + let account = &mut ctx.accounts.account; + let authority = &mut ctx.accounts.authority; + + account.data_f32 = data_f32; + account.data_f64 = data_f64; + account.authority = authority.key(); + + Ok(()) + } + + pub fn update(ctx: Context, data_f32: f32, data_f64: f64) -> ProgramResult { + let account = &mut ctx.accounts.account; + + account.data_f32 = data_f32; + account.data_f64 = data_f64; + + Ok(()) + } +} + +#[derive(Accounts)] +pub struct Create<'info> { + #[account(init, payer = authority, space = 8 + 8 + 4 + 32)] + pub account: Account<'info, FloatDataAccount>, + #[account(mut)] + pub authority: Signer<'info>, + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Update<'info> { + #[account(mut, has_one = authority)] + pub account: Account<'info, FloatDataAccount>, + pub authority: Signer<'info>, +} + +#[account] +pub struct FloatDataAccount { + pub data_f64: f64, + pub data_f32: f32, + pub authority: Pubkey, +} diff --git a/tests/floats/tests/floats.ts b/tests/floats/tests/floats.ts new file mode 100644 index 0000000000..06a6e12399 --- /dev/null +++ b/tests/floats/tests/floats.ts @@ -0,0 +1,67 @@ +import * as anchor from "@project-serum/anchor"; +import { Program, getProvider } from "@project-serum/anchor"; +import { Keypair, SystemProgram } from "@solana/web3.js"; +import { Floats } from "../target/types/floats"; +import assert from "assert"; + +describe("floats", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.Provider.env()); + + const program = anchor.workspace.Floats as Program; + + it("Creates an account with float data", async () => { + const accountKeypair = Keypair.generate(); + + await program.methods + .create(1.0, 2.0) + .accounts({ + account: accountKeypair.publicKey, + authority: getProvider().wallet.publicKey, + systemProgram: SystemProgram.programId, + }) + .signers([accountKeypair]) + .rpc(); + + const account = await program.account.floatDataAccount.fetch( + accountKeypair.publicKey + ); + + assert.strictEqual(account.dataF32, 1.0); + assert.strictEqual(account.dataF64, 2.0); + }); + + it("Updates an account with float data", async () => { + const accountKeypair = Keypair.generate(); + const authorityPublicKey = getProvider().wallet.publicKey; + + await program.methods + .create(1.0, 2.0) + .accounts({ + account: accountKeypair.publicKey, + authority: authorityPublicKey, + systemProgram: SystemProgram.programId, + }) + .signers([accountKeypair]) + .rpc(); + + let account = await program.account.floatDataAccount.fetch( + accountKeypair.publicKey + ); + + await program.methods + .update(3.0, 4.0) + .accounts({ + account: accountKeypair.publicKey, + authority: authorityPublicKey, + }) + .rpc(); + + account = await program.account.floatDataAccount.fetch( + accountKeypair.publicKey + ); + + assert.strictEqual(account.dataF32, 3.0); + assert.strictEqual(account.dataF64, 4.0); + }); +}); diff --git a/tests/floats/tsconfig.json b/tests/floats/tsconfig.json new file mode 100644 index 0000000000..cd5d2e3d06 --- /dev/null +++ b/tests/floats/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } +} diff --git a/tests/package.json b/tests/package.json index 7159a5d679..78240c72bb 100644 --- a/tests/package.json +++ b/tests/package.json @@ -14,6 +14,7 @@ "errors", "escrow", "events", + "floats", "ido-pool", "interface", "lockup", diff --git a/ts/package.json b/ts/package.json index 418000c4e1..c5555de400 100644 --- a/ts/package.json +++ b/ts/package.json @@ -33,7 +33,7 @@ "test": "jest tests --detectOpenHandles" }, "dependencies": { - "@project-serum/borsh": "^0.2.4", + "@project-serum/borsh": "^0.2.5", "@solana/web3.js": "^1.17.0", "base64-js": "^1.5.1", "bn.js": "^5.1.2", diff --git a/ts/src/coder/borsh/idl.ts b/ts/src/coder/borsh/idl.ts index 304fe70555..b7ec0e8a3d 100644 --- a/ts/src/coder/borsh/idl.ts +++ b/ts/src/coder/borsh/idl.ts @@ -33,12 +33,18 @@ export class IdlCoder { case "i32": { return borsh.i32(fieldName); } + case "f32": { + return borsh.f32(fieldName); + } case "u64": { return borsh.u64(fieldName); } case "i64": { return borsh.i64(fieldName); } + case "f64": { + return borsh.f64(fieldName); + } case "u128": { return borsh.u128(fieldName); } diff --git a/ts/src/coder/common.ts b/ts/src/coder/common.ts index 8b6e26f989..39521f9008 100644 --- a/ts/src/coder/common.ts +++ b/ts/src/coder/common.ts @@ -46,10 +46,14 @@ function typeSize(idl: Idl, ty: IdlType): number { return 4; case "i32": return 4; + case "f32": + return 4; case "u64": return 8; case "i64": return 8; + case "f64": + return 8; case "u128": return 16; case "i128": diff --git a/ts/src/idl.ts b/ts/src/idl.ts index 2a20f61535..7587c1a48b 100644 --- a/ts/src/idl.ts +++ b/ts/src/idl.ts @@ -101,8 +101,10 @@ export type IdlType = | "i16" | "u32" | "i32" + | "f32" | "u64" | "i64" + | "f64" | "u128" | "i128" | "bytes" diff --git a/ts/src/program/namespace/types.ts b/ts/src/program/namespace/types.ts index be278dfde6..1fe703a651 100644 --- a/ts/src/program/namespace/types.ts +++ b/ts/src/program/namespace/types.ts @@ -94,7 +94,7 @@ type TypeMap = { bool: boolean; string: string; } & { - [K in "u8" | "i8" | "u16" | "i16" | "u32" | "i32"]: number; + [K in "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "f32" | "f64"]: number; } & { [K in "u64" | "i64" | "u128" | "i128"]: BN; diff --git a/ts/yarn.lock b/ts/yarn.lock index 8f140c23cb..fa355de3d2 100644 --- a/ts/yarn.lock +++ b/ts/yarn.lock @@ -855,10 +855,10 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@project-serum/borsh@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.4.tgz#8884c3a759984a39d54bf5b7390bd1ee0b579f16" - integrity sha512-tQPc1ktAp1Jtn9D72DmObAfhAic9ivfYBOS5b+T4H7MvkQ84uML88LY1LfvGep30mCy+ua5rf+X9ocPfg6u9MA== +"@project-serum/borsh@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.5.tgz#6059287aa624ecebbfc0edd35e4c28ff987d8663" + integrity sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q== dependencies: bn.js "^5.1.2" buffer-layout "^1.2.0"