From 2d6f2261fc0a85af1f205f90e30827cfa8d03dfb Mon Sep 17 00:00:00 2001 From: Harsh Ghodkar Date: Wed, 23 Mar 2022 18:32:40 +0530 Subject: [PATCH 1/3] ported memo to anchor --- memo/anchor_program/memo/Cargo.toml | 19 ++++++ memo/anchor_program/memo/Xargo.toml | 2 + memo/anchor_program/memo/src/lib.rs | 50 +++++++++++++++ memo/anchor_program/tests/memo.js | 98 +++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 memo/anchor_program/memo/Cargo.toml create mode 100644 memo/anchor_program/memo/Xargo.toml create mode 100644 memo/anchor_program/memo/src/lib.rs create mode 100644 memo/anchor_program/tests/memo.js diff --git a/memo/anchor_program/memo/Cargo.toml b/memo/anchor_program/memo/Cargo.toml new file mode 100644 index 00000000000..b8a21f790c5 --- /dev/null +++ b/memo/anchor_program/memo/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "memo" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "memo" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +anchor-lang = "0.22.0" diff --git a/memo/anchor_program/memo/Xargo.toml b/memo/anchor_program/memo/Xargo.toml new file mode 100644 index 00000000000..475fb71ed15 --- /dev/null +++ b/memo/anchor_program/memo/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/memo/anchor_program/memo/src/lib.rs b/memo/anchor_program/memo/src/lib.rs new file mode 100644 index 00000000000..310fee0fe74 --- /dev/null +++ b/memo/anchor_program/memo/src/lib.rs @@ -0,0 +1,50 @@ +use anchor_lang::prelude::*; + +declare_id!("4ARKJpztrkSJXJQ8ii9pr6NjJdwKrC6M3jA8LG21tvjG"); + +#[program] +pub mod memo { + use super::*; + use std::str; + pub fn build_memo(ctx: Context,input:Vec) -> Result<()> { + + msg!("Initializing"); + + let accounts = ctx.remaining_accounts; + + let mut missing_required_signature = false; + for account_info in accounts.iter() { + if let Some(address) = account_info.signer_key() { + msg!("Signed by: {:?}", address); + } + else{ + missing_required_signature = true; + } + } + if missing_required_signature{ + return err!(MyError::MissingRequiredSignature); + } + + let memo = str::from_utf8(&input).map_err(|err| { + msg!("Invalid UTF-8, from bytes: {:?}", err); + ProgramError::InvalidInstructionData + })?; + msg!("Memo (len {}): {:?}", memo.len(), memo); + Ok(()) + } +} + +#[derive(Accounts)] +pub struct BuildMemo<> { + +} + + +#[error_code] +pub enum MyError { + #[msg("Missing required signature")] + MissingRequiredSignature, + #[msg("Invalid Instruction Data")] + InvalidInstructionData +} + diff --git a/memo/anchor_program/tests/memo.js b/memo/anchor_program/tests/memo.js new file mode 100644 index 00000000000..d3cbcaf15e7 --- /dev/null +++ b/memo/anchor_program/tests/memo.js @@ -0,0 +1,98 @@ +const anchor = require("@project-serum/anchor"); +const assert = require("assert"); + +describe("memo", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.Provider.env()); + const program = anchor.workspace.Memo; + + it("Test 1 => Sending Buffers", async () => { + const string = "letters"; + var codedString = Buffer.from(string); + + const tx = await program.rpc.buildMemo(codedString); + console.log("Transaction Signature:", tx); + }); + + it("Test 2 => Asserting Emojis and Bytes", async () => { + let emoji = Uint8Array.from(Buffer.from("🐆")); + let bytes = Uint8Array.from([0xf0, 0x9f, 0x90, 0x86]); + assert.equal(emoji.toString(), bytes.toString()); + + const tx1 = await program.rpc.buildMemo(Buffer.from("🐆")); + + const tx2 = await program.rpc.buildMemo(Buffer.from(bytes)); + console.log("Transaction Signature One:", tx1); + console.log("Transaction Signature Two:", tx2); + }); + + it("Test 3 => Sending Signed Transaction", async () => { + const pubkey1 = anchor.web3.Keypair.generate(); + const pubkey2 = anchor.web3.Keypair.generate(); + const pubkey3 = anchor.web3.Keypair.generate(); + + const tx = await program.rpc.buildMemo(Buffer.from("🐆"), { + accounts: [], + remainingAccounts: [ + { pubkey: pubkey1.publicKey, isWritable: false, isSigner: true }, + { pubkey: pubkey2.publicKey, isWritable: false, isSigner: true }, + { pubkey: pubkey3.publicKey, isWritable: false, isSigner: true }, + ], + signers: [pubkey1, pubkey2, pubkey3], + }); + console.log("Transaction Signature:", tx); + }); + + it("Test 4 => Sending Unsigned Transaction with a Memo", async () => { + // This test should fail because the transaction is not signed. + const pubkey1 = anchor.web3.Keypair.generate(); + const pubkey2 = anchor.web3.Keypair.generate(); + const pubkey3 = anchor.web3.Keypair.generate(); + + assert.rejects(() => { + program.rpc.buildMemo(Buffer.from("🐆"), { + accounts: [], + remainingAccounts: [ + { pubkey: pubkey1.publicKey, isWritable: false, isSigner: false }, + { pubkey: pubkey2.publicKey, isWritable: false, isSigner: false }, + { pubkey: pubkey3.publicKey, isWritable: false, isSigner: false }, + ], + signers: [pubkey1, pubkey2, pubkey3], + }); + }, new Error("unknown signer")); + + console.log("Test failed successfully :)"); + }); + + it("Test 5 => Sending a transaction with missing signers", async () => { + // This test should fail because the transaction is not signed completely. + const pubkey1 = anchor.web3.Keypair.generate(); + const pubkey2 = anchor.web3.Keypair.generate(); + const pubkey3 = anchor.web3.Keypair.generate(); + + assert.rejects(async () => { + await program.rpc.buildMemo(Buffer.from("🐆"), { + accounts: [], + remainingAccounts: [ + { pubkey: pubkey1.publicKey, isWritable: false, isSigner: true }, + { pubkey: pubkey2.publicKey, isWritable: false, isSigner: false }, + { pubkey: pubkey3.publicKey, isWritable: false, isSigner: true }, + ], + signers: [pubkey1, pubkey2, pubkey3], + }); + }, new Error("unknown signer")); + console.log("Test failed successfully :)"); + }); + + it("Test 6 => Testing invalid input", async () => { + // This test should fail because the input is invalid. + let invalid_utf8 = Uint8Array.from([ + 0xf0, 0x9f, 0x90, 0x86, 0xf0, 0x9f, 0xff, 0x86, + ]); + + assert.rejects(() => { + program.rpc.buildMemo(Buffer.from(invalid_utf8)); + }, new Error()); + console.log("Test failed successfully :)"); + }); +}); From 341bc310efacdea2621da6cb369aa061362416ce Mon Sep 17 00:00:00 2001 From: Harsh Ghodkar Date: Sun, 27 Mar 2022 18:38:50 +0530 Subject: [PATCH 2/3] updated as per the reviews --- memo/anchor_program/memo/src/lib.rs | 29 ++++----------- memo/anchor_program/tests/memo.js | 56 ++++++++++++++--------------- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/memo/anchor_program/memo/src/lib.rs b/memo/anchor_program/memo/src/lib.rs index 310fee0fe74..1cbf76d0a80 100644 --- a/memo/anchor_program/memo/src/lib.rs +++ b/memo/anchor_program/memo/src/lib.rs @@ -6,23 +6,20 @@ declare_id!("4ARKJpztrkSJXJQ8ii9pr6NjJdwKrC6M3jA8LG21tvjG"); pub mod memo { use super::*; use std::str; - pub fn build_memo(ctx: Context,input:Vec) -> Result<()> { - - msg!("Initializing"); - + pub fn log_memo(ctx: Context, input: Vec) -> Result<()> { let accounts = ctx.remaining_accounts; let mut missing_required_signature = false; for account_info in accounts.iter() { if let Some(address) = account_info.signer_key() { msg!("Signed by: {:?}", address); - } - else{ + } else { missing_required_signature = true; } } - if missing_required_signature{ - return err!(MyError::MissingRequiredSignature); + if missing_required_signature { + msg!("Missing required signature"); + return Err(ProgramError::MissingRequiredSignature.into()); } let memo = str::from_utf8(&input).map_err(|err| { @@ -31,20 +28,8 @@ pub mod memo { })?; msg!("Memo (len {}): {:?}", memo.len(), memo); Ok(()) - } + } } #[derive(Accounts)] -pub struct BuildMemo<> { - -} - - -#[error_code] -pub enum MyError { - #[msg("Missing required signature")] - MissingRequiredSignature, - #[msg("Invalid Instruction Data")] - InvalidInstructionData -} - +pub struct BuildMemo {} diff --git a/memo/anchor_program/tests/memo.js b/memo/anchor_program/tests/memo.js index d3cbcaf15e7..5c8c72489d2 100644 --- a/memo/anchor_program/tests/memo.js +++ b/memo/anchor_program/tests/memo.js @@ -10,7 +10,7 @@ describe("memo", () => { const string = "letters"; var codedString = Buffer.from(string); - const tx = await program.rpc.buildMemo(codedString); + const tx = await program.rpc.logMemo(codedString); console.log("Transaction Signature:", tx); }); @@ -19,45 +19,45 @@ describe("memo", () => { let bytes = Uint8Array.from([0xf0, 0x9f, 0x90, 0x86]); assert.equal(emoji.toString(), bytes.toString()); - const tx1 = await program.rpc.buildMemo(Buffer.from("🐆")); + const tx1 = await program.rpc.logMemo(Buffer.from("🐆")); - const tx2 = await program.rpc.buildMemo(Buffer.from(bytes)); + const tx2 = await program.rpc.logMemo(Buffer.from(bytes)); console.log("Transaction Signature One:", tx1); console.log("Transaction Signature Two:", tx2); }); it("Test 3 => Sending Signed Transaction", async () => { - const pubkey1 = anchor.web3.Keypair.generate(); - const pubkey2 = anchor.web3.Keypair.generate(); - const pubkey3 = anchor.web3.Keypair.generate(); + const account1 = anchor.web3.Keypair.generate(); + const account2 = anchor.web3.Keypair.generate(); + const account3 = anchor.web3.Keypair.generate(); - const tx = await program.rpc.buildMemo(Buffer.from("🐆"), { + const tx = await program.rpc.logMemo(Buffer.from("🐆"), { accounts: [], remainingAccounts: [ - { pubkey: pubkey1.publicKey, isWritable: false, isSigner: true }, - { pubkey: pubkey2.publicKey, isWritable: false, isSigner: true }, - { pubkey: pubkey3.publicKey, isWritable: false, isSigner: true }, + { pubkey: account1.publicKey, isWritable: false, isSigner: true }, + { pubkey: account2.publicKey, isWritable: false, isSigner: true }, + { pubkey: account3.publicKey, isWritable: false, isSigner: true }, ], - signers: [pubkey1, pubkey2, pubkey3], + signers: [account1, account2, account3], }); console.log("Transaction Signature:", tx); }); it("Test 4 => Sending Unsigned Transaction with a Memo", async () => { // This test should fail because the transaction is not signed. - const pubkey1 = anchor.web3.Keypair.generate(); - const pubkey2 = anchor.web3.Keypair.generate(); - const pubkey3 = anchor.web3.Keypair.generate(); + const account1 = anchor.web3.Keypair.generate(); + const account2 = anchor.web3.Keypair.generate(); + const account3 = anchor.web3.Keypair.generate(); assert.rejects(() => { - program.rpc.buildMemo(Buffer.from("🐆"), { + program.rpc.logMemo(Buffer.from("🐆"), { accounts: [], remainingAccounts: [ - { pubkey: pubkey1.publicKey, isWritable: false, isSigner: false }, - { pubkey: pubkey2.publicKey, isWritable: false, isSigner: false }, - { pubkey: pubkey3.publicKey, isWritable: false, isSigner: false }, + { pubkey: account1.publicKey, isWritable: false, isSigner: false }, + { pubkey: account2.publicKey, isWritable: false, isSigner: false }, + { pubkey: account3.publicKey, isWritable: false, isSigner: false }, ], - signers: [pubkey1, pubkey2, pubkey3], + signers: [account1, account2, account3], }); }, new Error("unknown signer")); @@ -66,19 +66,19 @@ describe("memo", () => { it("Test 5 => Sending a transaction with missing signers", async () => { // This test should fail because the transaction is not signed completely. - const pubkey1 = anchor.web3.Keypair.generate(); - const pubkey2 = anchor.web3.Keypair.generate(); - const pubkey3 = anchor.web3.Keypair.generate(); + const account1 = anchor.web3.Keypair.generate(); + const account2 = anchor.web3.Keypair.generate(); + const account3 = anchor.web3.Keypair.generate(); assert.rejects(async () => { - await program.rpc.buildMemo(Buffer.from("🐆"), { + await program.rpc.logMemo(Buffer.from("🐆"), { accounts: [], remainingAccounts: [ - { pubkey: pubkey1.publicKey, isWritable: false, isSigner: true }, - { pubkey: pubkey2.publicKey, isWritable: false, isSigner: false }, - { pubkey: pubkey3.publicKey, isWritable: false, isSigner: true }, + { pubkey: account1.publicKey, isWritable: false, isSigner: true }, + { pubkey: account2.publicKey, isWritable: false, isSigner: false }, + { pubkey: account3.publicKey, isWritable: false, isSigner: true }, ], - signers: [pubkey1, pubkey2, pubkey3], + signers: [account1, account2, account3], }); }, new Error("unknown signer")); console.log("Test failed successfully :)"); @@ -91,7 +91,7 @@ describe("memo", () => { ]); assert.rejects(() => { - program.rpc.buildMemo(Buffer.from(invalid_utf8)); + program.rpc.logMemo(Buffer.from(invalid_utf8)); }, new Error()); console.log("Test failed successfully :)"); }); From d2b192c8635c2a0ee9579ef28aaf9223781b5397 Mon Sep 17 00:00:00 2001 From: Harsh Ghodkar Date: Wed, 6 Apr 2022 19:43:06 +0530 Subject: [PATCH 3/3] removed a log --- memo/anchor_program/memo/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/memo/anchor_program/memo/src/lib.rs b/memo/anchor_program/memo/src/lib.rs index 1cbf76d0a80..b84728ef63e 100644 --- a/memo/anchor_program/memo/src/lib.rs +++ b/memo/anchor_program/memo/src/lib.rs @@ -18,7 +18,6 @@ pub mod memo { } } if missing_required_signature { - msg!("Missing required signature"); return Err(ProgramError::MissingRequiredSignature.into()); }