Skip to content

Commit

Permalink
Make sure deployment works
Browse files Browse the repository at this point in the history
  • Loading branch information
acheroncrypto committed Apr 22, 2022
1 parent fb04b87 commit b9b8028
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 56 deletions.
4 changes: 2 additions & 2 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PhantomWalletAdapter } from "@solana/wallet-adapter-phantom";

import MutThemeProvider from "./theme/";
import IDE from "./pages/ide";
import { endpointAtom } from "./state/solana";
import { endpointAtom } from "./state";

const App = () => {
const [endpoint] = useAtom(endpointAtom);
Expand All @@ -18,7 +18,7 @@ const App = () => {
<MutThemeProvider>
<ConnectionProvider
endpoint={endpoint}
config={{ commitment: "processed" }}
config={{ commitment: "confirmed" }}
>
<WalletProvider wallets={wallets}>
<IDE />
Expand Down
17 changes: 11 additions & 6 deletions client/src/components/Panels/Side/Right/Deploy/Deploy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import { useConnection } from "@solana/wallet-adapter-react";
import styled from "styled-components";

import Button from "../../../../Button";
import Text from "../../../../Text";
import { PgDeploy } from "../../../../../utils/pg/deploy";
import { PgProgramInfo } from "../../../../../utils/pg/program-info";
import { terminalAtom } from "../../../../../state";
import { pgWalletAtom, refreshPgWalletAtom } from "../../../../../state/solana";
import Text from "../../../../Text";
import {
terminalAtom,
pgWalletAtom,
refreshPgWalletAtom,
} from "../../../../../state";
import { PgError } from "../../../../../utils/pg/error";

const Deploy = () => {
Expand All @@ -29,9 +32,11 @@ const Deploy = () => {

const deploy = useCallback(async () => {
if (!pgWallet.connected) return;
setLoading(true);

setTerminal("Deploying...");
setLoading(true);
setTerminal(
"Deploying... This could take a while depending on the program size and network conditions."
);

let msg = "";

Expand All @@ -40,7 +45,7 @@ const Deploy = () => {

PgProgramInfo.updateProgramInfo({ deployed: true });

msg = "Deployment successful";
msg = "Deployment successful.";
} catch (e: any) {
const convertedError = PgError.convertErrorMessage(e.message);
msg = `Deployment error: ${convertedError}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useAtom } from "jotai";
import { ChangeEvent, useCallback, useMemo } from "react";
import { useAtom } from "jotai";

import { endpointAtom } from "../../../../../state";
import { NETWORKS } from "../../../../../constants";
import { endpointAtom } from "../../../../../state/solana";
import { PgEndpoint } from "../../../../../utils/pg/endpoint";
import Select from "../../../../Select";

Expand Down
3 changes: 1 addition & 2 deletions client/src/components/Panels/Side/Right/Wallet/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import { useConnection } from "@solana/wallet-adapter-react";
import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
import styled, { css } from "styled-components";

import { terminalAtom } from "../../../../../state";
import { terminalAtom, endpointAtom } from "../../../../../state";
import { PgTx } from "../../../../../utils/pg/tx";
import Button from "../../../../Button";
import useConnect from "./useConnect";
import useCurrentWallet from "./useCurrentWallet";
import { endpointAtom } from "../../../../../state/solana";
import { Endpoints } from "../../../../../constants";

const Wallet = () => {
Expand Down
7 changes: 5 additions & 2 deletions client/src/components/Panels/Side/Right/Wallet/useConnect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { useAtom } from "jotai";
import { useWallet } from "@solana/wallet-adapter-react";

import { ConnState } from "./connection-states";
import { pgWalletAtom, refreshPgWalletAtom } from "../../../../../state/solana";
import {
modalAtom,
pgWalletAtom,
refreshPgWalletAtom,
} from "../../../../../state";
import { PgWallet } from "../../../../../utils/pg/wallet";
import Setup from "./Setup";
import { modalAtom } from "../../../../../state";

const useConnect = () => {
// Pg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from "react";
import { useAtom } from "jotai";
import { AnchorWallet, useAnchorWallet } from "@solana/wallet-adapter-react";

import { pgWalletAtom, refreshPgWalletAtom } from "../../../../../state/solana";
import { pgWalletAtom, refreshPgWalletAtom } from "../../../../../state";
import { PgWallet } from "../../../../../utils/pg/wallet";

const useCurrentWallet = () => {
Expand Down
9 changes: 7 additions & 2 deletions client/src/constants/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ export enum ItemError {
INVALID_NAME = "Invalid name",
}

interface ProgramError {
interface ConvertedError {
[key: string]: string;
}

export const PROGRAM_ERROR: ProgramError = {
export const PROGRAM_ERROR: ConvertedError = {
"0": "Either the account has already been initialized or new account balance is below rent-exempt threshold",
"1": "Insufficient funds",
"2": "Invalid Mint(token address)",
Expand All @@ -29,3 +29,8 @@ export const PROGRAM_ERROR: ProgramError = {
"12": "The provided decimals value different from the Mint decimals",
"13": "Instruction does not support non-native tokens",
};

export const RPC_ERROR: ConvertedError = {
"503 Service Unavailable":
"RPC unavailable. Please try a different endpoint from the settings or try again.",
};
1 change: 1 addition & 0 deletions client/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from "./explorer";
export * from "./modal";
export * from "./editor";
export * from "./terminal";
export * from "./solana";
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { encodeData, InstructionType } from "./instruction";
import * as Layout from "./layout";
import { PgTx } from "../pg/tx";
import { PgWallet } from "../pg/wallet";
import { PgCommon } from "../pg/common";

const BPF_LOADER_UPGRADEABLE_PROGRAM_ID = new PublicKey(
"BPFLoaderUpgradeab1e11111111111111111111111"
Expand Down Expand Up @@ -510,8 +511,26 @@ export class BpfLoaderUpgradeable {
})
);

await PgTx.send(tx, conn, wallet);
let writeTxHash;
// Retry until writing is successful
for (;;) {
try {
writeTxHash = await PgTx.send(tx, conn, wallet);

const result = await conn.confirmTransaction(writeTxHash);
console.count("buffer write");

if (!result?.value.err) break;
} catch (e: any) {
console.log("Buffer write error:", e.message);

// Sleep incase of being rate-limited
await PgCommon.sleep(2000);
}
}
}

console.countReset("buffer write");
})
);
}
Expand Down
109 changes: 73 additions & 36 deletions client/src/utils/pg/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Connection, Keypair } from "@solana/web3.js";
import { Buffer } from "buffer";
import { Connection, Keypair } from "@solana/web3.js";

import { BpfLoaderUpgradeable } from "../bpf-upgradeable-browser";
import { PgCommon } from "./common";
import { SERVER_URL } from "../../constants";
import { PgProgramInfo } from "./program-info";
import { PgCommon } from "./common";
import { PgWallet } from "./wallet";

export class PgDeploy {
static async deploy(conn: Connection, wallet: PgWallet) {
// Only get the binary if it's not in the localStorage
const uuid = PgProgramInfo.getProgramInfo().uuid;
const resp = await fetch(`${SERVER_URL}/deploy/${uuid}`);

Expand Down Expand Up @@ -41,10 +40,22 @@ export class PgDeploy {
console.log("Buffer pk: " + bufferKp.publicKey.toBase58());

// Confirm the buffer has been created
let tries = 0;
while (1) {
const bufferInit = await conn.getAccountInfo(bufferKp.publicKey);
if (bufferInit) break;
await PgCommon.sleep(1000);

// Retry again every 5 tries
if (tries % 5)
await BpfLoaderUpgradeable.createBuffer(
conn,
wallet,
bufferKp,
bufferBalance,
programBuffer.length
);

await PgCommon.sleep(2000);
}

// Load buffer
Expand All @@ -65,40 +76,66 @@ export class PgDeploy {
if (programKpResult?.err) throw new Error(programKpResult.err);
const programKp = programKpResult.programKp!;

const programExists = await conn.getAccountInfo(programKp.publicKey);

let txHash;

if (!programExists) {
// Deploy
const programSize = BpfLoaderUpgradeable.getBufferAccountSize(
BpfLoaderUpgradeable.BUFFER_PROGRAM_SIZE
);
const programBalance = await conn.getMinimumBalanceForRentExemption(
programSize
);

txHash = await BpfLoaderUpgradeable.deployProgram(
conn,
wallet,
bufferKp.publicKey,
programKp,
programBalance,
programBuffer.length * 2
);

console.log("Deploy Program Tx Hash: ", txHash);
} else {
// Upgrade
txHash = await BpfLoaderUpgradeable.upgradeProgram(
programKp.publicKey,
conn,
wallet,
bufferKp.publicKey,
wallet.publicKey
);

console.log("Upgrade Program Tx Hash: ", txHash);
// Retry until it's successful
while (1) {
try {
const programExists = await conn.getAccountInfo(programKp.publicKey);

if (!programExists) {
// Deploy
const programSize = BpfLoaderUpgradeable.getBufferAccountSize(
BpfLoaderUpgradeable.BUFFER_PROGRAM_SIZE
);
const programBalance = await conn.getMinimumBalanceForRentExemption(
programSize
);

txHash = await BpfLoaderUpgradeable.deployProgram(
conn,
wallet,
bufferKp.publicKey,
programKp,
programBalance,
programBuffer.length * 2
);

console.log("Deploy Program Tx Hash: ", txHash);

const result = await conn.confirmTransaction(txHash);
if (!result?.value.err) break;
await BpfLoaderUpgradeable.deployProgram(
conn,
wallet,
bufferKp.publicKey,
programKp,
programBalance,
programBuffer.length * 2
);
} else {
// Upgrade
txHash = await BpfLoaderUpgradeable.upgradeProgram(
programKp.publicKey,
conn,
wallet,
bufferKp.publicKey,
wallet.publicKey
);

console.log("Upgrade Program Tx Hash: ", txHash);

const result = await conn.confirmTransaction(txHash);
if (!result?.value.err) break;
txHash = await BpfLoaderUpgradeable.upgradeProgram(
programKp.publicKey,
conn,
wallet,
bufferKp.publicKey,
wallet.publicKey
);
}
} catch {}
}

return txHash;
Expand Down
15 changes: 13 additions & 2 deletions client/src/utils/pg/error.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { PROGRAM_ERROR } from "../../constants";
import { PROGRAM_ERROR, RPC_ERROR } from "../../constants";

export class PgError {
static convertErrorMessage(msg: string) {
let changed = false;

// Program errors
for (const programErrorCode in PROGRAM_ERROR) {
if (msg.endsWith(programErrorCode)) {
if (msg.endsWith("0x" + programErrorCode)) {
msg = msg.replace(
`custom program error: 0x${programErrorCode}`,
PROGRAM_ERROR[programErrorCode]
);
changed = true;
break;
}
}

// Rpc errors
if (!changed) {
for (const rpcError in RPC_ERROR) {
if (msg.includes(rpcError)) msg = RPC_ERROR[rpcError];
}
}

return msg;
}
}

0 comments on commit b9b8028

Please sign in to comment.