Browse Source

Revert "Simple Versioned Transaction Support (#2407)" (#2426)

This reverts commit 064dde4b1aae9bc6193afdf3beece82efcd6ab87.
Henry-E 2 years ago
parent
commit
1dc16d6642
4 changed files with 58 additions and 222 deletions
  1. 0 1
      CHANGELOG.md
  2. 0 100
      tests/misc/tests/misc/misc.ts
  3. 5 22
      ts/packages/anchor/src/nodewallet.ts
  4. 53 99
      ts/packages/anchor/src/provider.ts

+ 0 - 1
CHANGELOG.md

@@ -23,7 +23,6 @@ The minor version will be incremented upon a breaking change and the patch versi
 - client: Add support for multithreading to the rust client: use flag `--multithreaded` ([#2321](https://github.com/coral-xyz/anchor/pull/2321)).
 - client: Add `async_rpc` a method which returns a nonblocking solana rpc client ([2322](https://github.com/coral-xyz/anchor/pull/2322)).
 - avm, cli: Use the `rustls-tls` feature of `reqwest` so that users don't need OpenSSL installed ([#2385](https://github.com/coral-xyz/anchor/pull/2385)).
-- ts: Add `VersionedTransaction` support. Methods in the `Provider` class and `Wallet` interface now use the argument `tx: Transaction | VersionedTransaction` ([2407](https://github.com/coral-xyz/anchor/pull/2407)).
 - cli: Add `--arch sbf` option to compile programs using `cargo build-sbf` ([#2398](https://github.com/coral-xyz/anchor/pull/2398)).
 
 ### Fixes

+ 0 - 100
tests/misc/tests/misc/misc.ts

@@ -6,8 +6,6 @@ import {
   SystemProgram,
   Message,
   VersionedTransaction,
-  AddressLookupTableProgram,
-  TransactionMessage,
 } from "@solana/web3.js";
 import {
   TOKEN_PROGRAM_ID,
@@ -63,104 +61,6 @@ const miscTest = (
       assert.strictEqual(dataAccount.data, 99);
     });
 
-    it("Can send VersionedTransaction", async () => {
-      // Create the lookup table
-      const recentSlot = await provider.connection.getSlot();
-      const [loookupTableInstruction, lookupTableAddress] =
-        AddressLookupTableProgram.createLookupTable({
-          authority: provider.publicKey,
-          payer: provider.publicKey,
-          recentSlot,
-        });
-      const extendInstruction = AddressLookupTableProgram.extendLookupTable({
-        payer: provider.publicKey,
-        authority: provider.publicKey,
-        lookupTable: lookupTableAddress,
-        addresses: [provider.publicKey, SystemProgram.programId],
-      });
-      let createLookupTableTx = new VersionedTransaction(
-        new TransactionMessage({
-          instructions: [loookupTableInstruction, extendInstruction],
-          payerKey: program.provider.publicKey,
-          recentBlockhash: (await provider.connection.getLatestBlockhash())
-            .blockhash,
-        }).compileToV0Message()
-      );
-      await provider.sendAndConfirm(createLookupTableTx, [], {
-        skipPreflight: true,
-      });
-
-      // Use the lookup table in a transaction
-      const transferAmount = 1_000_000;
-      const lookupTableAccount = await provider.connection
-        .getAddressLookupTable(lookupTableAddress)
-        .then((res) => res.value);
-      const target = anchor.web3.Keypair.generate();
-      let transferInstruction = SystemProgram.transfer({
-        fromPubkey: provider.publicKey,
-        lamports: transferAmount,
-        toPubkey: target.publicKey,
-      });
-      let transferUsingLookupTx = new VersionedTransaction(
-        new TransactionMessage({
-          instructions: [transferInstruction],
-          payerKey: program.provider.publicKey,
-          recentBlockhash: (await provider.connection.getLatestBlockhash())
-            .blockhash,
-        }).compileToV0Message([lookupTableAccount])
-      );
-      await provider.simulate(transferUsingLookupTx, [], "processed");
-      await provider.sendAndConfirm(transferUsingLookupTx, [], {
-        skipPreflight: true,
-        commitment: "confirmed",
-      });
-      let newBalance = await provider.connection.getBalance(
-        target.publicKey,
-        "confirmed"
-      );
-      assert.strictEqual(newBalance, transferAmount);
-
-      // Test sendAll with versioned transaction
-      let oneTransferUsingLookupTx = new VersionedTransaction(
-        new TransactionMessage({
-          instructions: [
-            SystemProgram.transfer({
-              fromPubkey: provider.publicKey,
-              // Needed to make the transactions distinct
-              lamports: transferAmount + 1,
-              toPubkey: target.publicKey,
-            }),
-          ],
-          payerKey: program.provider.publicKey,
-          recentBlockhash: (await provider.connection.getLatestBlockhash())
-            .blockhash,
-        }).compileToV0Message([lookupTableAccount])
-      );
-      let twoTransferUsingLookupTx = new VersionedTransaction(
-        new TransactionMessage({
-          instructions: [
-            SystemProgram.transfer({
-              fromPubkey: provider.publicKey,
-              lamports: transferAmount,
-              toPubkey: target.publicKey,
-            }),
-          ],
-          payerKey: program.provider.publicKey,
-          recentBlockhash: (await provider.connection.getLatestBlockhash())
-            .blockhash,
-        }).compileToV0Message([lookupTableAccount])
-      );
-      await provider.sendAll(
-        [{ tx: oneTransferUsingLookupTx }, { tx: twoTransferUsingLookupTx }],
-        { skipPreflight: true, commitment: "confirmed" }
-      );
-      newBalance = await provider.connection.getBalance(
-        target.publicKey,
-        "confirmed"
-      );
-      assert.strictEqual(newBalance, transferAmount * 3 + 1);
-    });
-
     it("Can embed programs into genesis from the Anchor.toml", async () => {
       const pid = new anchor.web3.PublicKey(
         "FtMNMKp9DZHKWUyVAsj3Q5QV8ow4P3fUPP7ZrWEQJzKr"

+ 5 - 22
ts/packages/anchor/src/nodewallet.ts

@@ -1,10 +1,5 @@
 import { Buffer } from "buffer";
-import {
-  Keypair,
-  PublicKey,
-  Transaction,
-  VersionedTransaction,
-} from "@solana/web3.js";
+import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
 import { Wallet } from "./provider";
 
 /**
@@ -35,26 +30,14 @@ export default class NodeWallet implements Wallet {
     return new NodeWallet(payer);
   }
 
-  async signTransaction<T extends Transaction | VersionedTransaction>(
-    tx: T
-  ): Promise<T> {
-    if (tx instanceof VersionedTransaction) {
-      tx.sign([this.payer]);
-    } else {
-      tx.partialSign(this.payer);
-    }
+  async signTransaction(tx: Transaction): Promise<Transaction> {
+    tx.partialSign(this.payer);
     return tx;
   }
 
-  async signAllTransactions<T extends Transaction | VersionedTransaction>(
-    txs: T[]
-  ): Promise<T[]> {
+  async signAllTransactions(txs: Transaction[]): Promise<Transaction[]> {
     return txs.map((t) => {
-      if (t instanceof VersionedTransaction) {
-        t.sign([this.payer]);
-      } else {
-        t.partialSign(this.payer);
-      }
+      t.partialSign(this.payer);
       return t;
     });
   }

+ 53 - 99
ts/packages/anchor/src/provider.ts

@@ -9,8 +9,6 @@ import {
   Commitment,
   SendTransactionError,
   SendOptions,
-  VersionedTransaction,
-  RpcResponseAndContext,
 } from "@solana/web3.js";
 import { bs58 } from "./utils/bytes/index.js";
 import { isBrowser } from "./utils/common.js";
@@ -24,24 +22,21 @@ export default interface Provider {
   readonly publicKey?: PublicKey;
 
   send?(
-    tx: Transaction | VersionedTransaction,
+    tx: Transaction,
     signers?: Signer[],
     opts?: SendOptions
   ): Promise<TransactionSignature>;
   sendAndConfirm?(
-    tx: Transaction | VersionedTransaction,
+    tx: Transaction,
     signers?: Signer[],
     opts?: ConfirmOptions
   ): Promise<TransactionSignature>;
-  sendAll?<T extends Transaction | VersionedTransaction>(
-    txWithSigners: {
-      tx: T;
-      signers?: Signer[];
-    }[],
+  sendAll?(
+    txWithSigners: { tx: Transaction; signers?: Signer[] }[],
     opts?: ConfirmOptions
   ): Promise<Array<TransactionSignature>>;
   simulate?(
-    tx: Transaction | VersionedTransaction,
+    tx: Transaction,
     signers?: Signer[],
     commitment?: Commitment,
     includeAccounts?: boolean | PublicKey[]
@@ -129,7 +124,7 @@ export class AnchorProvider implements Provider {
    * @param opts    Transaction confirmation options.
    */
   async sendAndConfirm(
-    tx: Transaction | VersionedTransaction,
+    tx: Transaction,
     signers?: Signer[],
     opts?: ConfirmOptions
   ): Promise<TransactionSignature> {
@@ -137,23 +132,17 @@ export class AnchorProvider implements Provider {
       opts = this.opts;
     }
 
-    if (tx instanceof VersionedTransaction) {
-      if (signers) {
-        tx.sign(signers);
-      }
-    } else {
-      tx.feePayer = tx.feePayer ?? this.wallet.publicKey;
-      tx.recentBlockhash = (
-        await this.connection.getLatestBlockhash(opts.preflightCommitment)
-      ).blockhash;
-
-      if (signers) {
-        for (const signer of signers) {
-          tx.partialSign(signer);
-        }
-      }
-    }
+    tx.feePayer = tx.feePayer || this.wallet.publicKey;
+
+    tx.recentBlockhash = (
+      await this.connection.getLatestBlockhash(opts.preflightCommitment)
+    ).blockhash;
+
     tx = await this.wallet.signTransaction(tx);
+    (signers ?? []).forEach((kp) => {
+      tx.partialSign(kp);
+    });
+
     const rawTx = tx.serialize();
 
     try {
@@ -166,14 +155,10 @@ export class AnchorProvider implements Provider {
         // (the json RPC does not support any shorter than "confirmed" for 'getTransaction')
         // because that will see the tx sent with `sendAndConfirmRawTransaction` no matter which
         // commitment `sendAndConfirmRawTransaction` used
-        const txSig = bs58.encode(
-          tx instanceof VersionedTransaction
-            ? tx.signatures?.[0] || new Uint8Array()
-            : tx.signature ?? new Uint8Array()
+        const failedTx = await this.connection.getTransaction(
+          bs58.encode(tx.signature!),
+          { commitment: "confirmed" }
         );
-        const failedTx = await this.connection.getTransaction(txSig, {
-          commitment: "confirmed",
-        });
         if (!failedTx) {
           throw err;
         } else {
@@ -188,44 +173,34 @@ export class AnchorProvider implements Provider {
 
   /**
    * Similar to `send`, but for an array of transactions and signers.
-   * All transactions need to be of the same type, it doesn't support a mix of `VersionedTransaction`s and `Transaction`s.
    *
    * @param txWithSigners Array of transactions and signers.
    * @param opts          Transaction confirmation options.
    */
-  async sendAll<T extends Transaction | VersionedTransaction>(
-    txWithSigners: {
-      tx: T;
-      signers?: Signer[];
-    }[],
+  async sendAll(
+    txWithSigners: { tx: Transaction; signers?: Signer[] }[],
     opts?: ConfirmOptions
   ): Promise<Array<TransactionSignature>> {
     if (opts === undefined) {
       opts = this.opts;
     }
-    const recentBlockhash = (
-      await this.connection.getLatestBlockhash(opts.preflightCommitment)
-    ).blockhash;
+    const blockhash = await this.connection.getLatestBlockhash(
+      opts.preflightCommitment
+    );
 
     let txs = txWithSigners.map((r) => {
-      if (r.tx instanceof VersionedTransaction) {
-        let tx: VersionedTransaction = r.tx;
-        if (r.signers) {
-          tx.sign(r.signers);
-        }
-        return tx;
-      } else {
-        let tx: Transaction = r.tx;
-        let signers = r.signers ?? [];
+      let tx = r.tx;
+      let signers = r.signers ?? [];
 
-        tx.feePayer = tx.feePayer ?? this.wallet.publicKey;
-        tx.recentBlockhash = recentBlockhash;
+      tx.feePayer = tx.feePayer || this.wallet.publicKey;
 
-        signers.forEach((kp) => {
-          tx.partialSign(kp);
-        });
-        return tx;
-      }
+      tx.recentBlockhash = blockhash.blockhash;
+
+      signers.forEach((kp) => {
+        tx.partialSign(kp);
+      });
+
+      return tx;
     });
 
     const signedTxs = await this.wallet.signAllTransactions(txs);
@@ -248,14 +223,10 @@ export class AnchorProvider implements Provider {
           // (the json RPC does not support any shorter than "confirmed" for 'getTransaction')
           // because that will see the tx sent with `sendAndConfirmRawTransaction` no matter which
           // commitment `sendAndConfirmRawTransaction` used
-          const txSig = bs58.encode(
-            tx instanceof VersionedTransaction
-              ? tx.signatures?.[0] || new Uint8Array()
-              : tx.signature ?? new Uint8Array()
+          const failedTx = await this.connection.getTransaction(
+            bs58.encode(tx.signature!),
+            { commitment: "confirmed" }
           );
-          const failedTx = await this.connection.getTransaction(txSig, {
-            commitment: "confirmed",
-          });
           if (!failedTx) {
             throw err;
           } else {
@@ -282,42 +253,29 @@ export class AnchorProvider implements Provider {
    * @param opts    Transaction confirmation options.
    */
   async simulate(
-    tx: Transaction | VersionedTransaction,
+    tx: Transaction,
     signers?: Signer[],
     commitment?: Commitment,
     includeAccounts?: boolean | PublicKey[]
   ): Promise<SuccessfulTxSimulationResponse> {
-    let recentBlockhash = (
+    tx.feePayer = tx.feePayer || this.wallet.publicKey;
+
+    tx.recentBlockhash = (
       await this.connection.getLatestBlockhash(
         commitment ?? this.connection.commitment
       )
     ).blockhash;
 
-    let result: RpcResponseAndContext<SimulatedTransactionResponse>;
-    if (tx instanceof VersionedTransaction) {
-      if (signers) {
-        tx.sign(signers);
-        tx = await this.wallet.signTransaction(tx);
-      }
-
-      // Doesn't support includeAccounts which has been changed to something
-      // else in later versions of this function.
-      result = await this.connection.simulateTransaction(tx, { commitment });
-    } else {
-      tx.feePayer = tx.feePayer || this.wallet.publicKey;
-      tx.recentBlockhash = recentBlockhash;
-
-      if (signers) {
-        tx = await this.wallet.signTransaction(tx);
-      }
-      result = await simulateTransaction(
-        this.connection,
-        tx,
-        signers,
-        commitment,
-        includeAccounts
-      );
+    if (signers) {
+      tx = await this.wallet.signTransaction(tx);
     }
+    const result = await simulateTransaction(
+      this.connection,
+      tx,
+      signers,
+      commitment,
+      includeAccounts
+    );
 
     if (result.value.err) {
       throw new SimulateError(result.value);
@@ -345,12 +303,8 @@ export type SendTxRequest = {
  * Wallet interface for objects that can be used to sign provider transactions.
  */
 export interface Wallet {
-  signTransaction<T extends Transaction | VersionedTransaction>(
-    tx: T
-  ): Promise<T>;
-  signAllTransactions<T extends Transaction | VersionedTransaction>(
-    txs: T[]
-  ): Promise<T[]>;
+  signTransaction(tx: Transaction): Promise<Transaction>;
+  signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
   publicKey: PublicKey;
 }
 
@@ -358,7 +312,7 @@ export interface Wallet {
 // a better error if 'confirmTransaction` returns an error status
 async function sendAndConfirmRawTransaction(
   connection: Connection,
-  rawTransaction: Buffer | Uint8Array,
+  rawTransaction: Buffer,
   options?: ConfirmOptions
 ): Promise<TransactionSignature> {
   const sendOptions = options && {