Fetch logs with simulateTransaction when transactions fail

This commit is contained in:
Gary Wang 2020-12-10 04:10:13 +08:00
parent 42fec272c9
commit 3f21f90f77
6 changed files with 62 additions and 9 deletions

View File

@ -44,7 +44,7 @@
"build": "craco build", "build": "craco build",
"test": "craco test", "test": "craco test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"prettier": "prettier --write ." "prettier": "prettier --write src"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app"

View File

@ -100,7 +100,8 @@ export default function ListNewMarketPage() {
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
notify({ notify({
message: 'Error listing new market: ' + e.message, message: 'Error listing new market',
description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {

View File

@ -28,7 +28,7 @@ const AddRemoveTokenButtons = styled.div`
margin-bottom: 16px; margin-bottom: 16px;
`; `;
const DEFAULT_PROGRAM_ID = 'DL7L4cFHwmfNevZRg92rF5unbdUvFGoiuMrQ4aV7Nzsc'; const DEFAULT_PROGRAM_ID = 'CkMC9rHPB6xu7pQ3L49KUEYL6rcLJ25aKLLPcrNe5wLv';
export default function NewPoolPage() { export default function NewPoolPage() {
const connection = useConnection(); const connection = useConnection();
@ -100,7 +100,8 @@ export default function NewPoolPage() {
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
notify({ notify({
message: 'Error creating new pool: ' + e.message, message: 'Error creating new pool',
description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {

View File

@ -69,7 +69,8 @@ function PauseUnpauseTab({ poolInfo }: TabParams) {
await sendTransaction({ connection, wallet, transaction }); await sendTransaction({ connection, wallet, transaction });
} catch (e) { } catch (e) {
notify({ notify({
message: 'Error pausing pool: ' + e.message, message: 'Error pausing pool',
description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {
@ -88,7 +89,8 @@ function PauseUnpauseTab({ poolInfo }: TabParams) {
await sendTransaction({ connection, wallet, transaction }); await sendTransaction({ connection, wallet, transaction });
} catch (e) { } catch (e) {
notify({ notify({
message: 'Error unpausing pool: ' + e.message, message: 'Error unpausing pool',
description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {
@ -396,7 +398,8 @@ function useOnSubmitHandler(
} }
} catch (e) { } catch (e) {
notify({ notify({
message: `Error ${description}: ${e.message}`, message: `Error ${description}`,
description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {

View File

@ -119,8 +119,8 @@ function CreateRedeemTab({ poolInfo, mintInfo, tab }: CreateRedeemInnerPanel) {
message: message:
'Error ' + 'Error ' +
(tab === 'create' ? 'creating' : 'redeeming') + (tab === 'create' ? 'creating' : 'redeeming') +
' pool tokens: ' + ' pool tokens',
e.message, description: e.message,
type: 'error', type: 'error',
}); });
} finally { } finally {

View File

@ -4,9 +4,11 @@ import { getSelectedTokenAccountForMint } from './markets';
import { import {
Account, Account,
AccountInfo, AccountInfo,
Commitment,
Connection, Connection,
PublicKey, PublicKey,
RpcResponseAndContext, RpcResponseAndContext,
SimulatedTransactionResponse,
SystemProgram, SystemProgram,
Transaction, Transaction,
TransactionSignature, TransactionSignature,
@ -720,6 +722,25 @@ export async function sendSignedTransaction({
if (err.timeout) { if (err.timeout) {
throw new Error('Timed out awaiting confirmation on transaction'); throw new Error('Timed out awaiting confirmation on transaction');
} }
let simulateResult: SimulatedTransactionResponse | null = null;
try {
simulateResult = (
await simulateTransaction(connection, signedTransaction, 'single')
).value;
} catch (e) {}
if (simulateResult && simulateResult.err) {
if (simulateResult.logs) {
for (let i = simulateResult.logs.length - 1; i >= 0; --i) {
const line = simulateResult.logs[i];
if (line.startsWith('Program log: ')) {
throw new Error(
'Transaction failed: ' + line.slice('Program log: '.length),
);
}
}
}
throw new Error(JSON.stringify(simulateResult.err));
}
throw new Error('Transaction failed'); throw new Error('Transaction failed');
} finally { } finally {
done = true; done = true;
@ -903,3 +924,30 @@ export async function getMultipleSolanaAccounts(
), ),
}; };
} }
/** Copy of Connection.simulateTransaction that takes a commitment parameter. */
async function simulateTransaction(
connection: Connection,
transaction: Transaction,
commitment: Commitment,
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
// @ts-ignore
transaction.recentBlockhash = await connection._recentBlockhash(
// @ts-ignore
connection._disableBlockhashCaching,
);
const signData = transaction.serializeMessage();
// @ts-ignore
const wireTransaction = transaction._serialize(signData);
const encodedTransaction = wireTransaction.toString('base64');
const config: any = { encoding: 'base64', commitment };
const args = [encodedTransaction, config];
// @ts-ignore
const res = await connection._rpcRequest('simulateTransaction', args);
if (res.error) {
throw new Error('failed to simulate transaction: ' + res.error.message);
}
return res.result;
}