feat: add err field to status results

This commit is contained in:
Justin Starry 2020-04-04 21:35:08 +08:00 committed by Michael Vines
parent 3120e681d6
commit b0316f82b5
9 changed files with 63 additions and 59 deletions

View File

@ -5,6 +5,7 @@ declare module 'superstruct' {
array(schema: any): any; array(schema: any): any;
literal(schema: any): any; literal(schema: any): any;
tuple(schema: any): any; tuple(schema: any): any;
pick(schema: any): any;
}; };
declare module.exports: { declare module.exports: {

16
web3.js/module.d.ts vendored
View File

@ -50,7 +50,7 @@ declare module '@solana/web3.js' {
export type SignatureStatus = { export type SignatureStatus = {
slot: number; slot: number;
status: SignatureSuccess | TransactionError; err: TransactionError | null;
confirmations: number | null; confirmations: number | null;
}; };
@ -89,8 +89,8 @@ declare module '@solana/web3.js' {
fee: number; fee: number;
preBalances: Array<number>; preBalances: Array<number>;
postBalances: Array<number>; postBalances: Array<number>;
status?: SignatureSuccess | TransactionError; err: TransactionError | null;
}; } | null;
}>; }>;
}; };
@ -126,16 +126,14 @@ declare module '@solana/web3.js' {
) => void; ) => void;
export type SlotChangeCallback = (slotInfo: SlotInfo) => void; export type SlotChangeCallback = (slotInfo: SlotInfo) => void;
export type SignatureResultCallback = ( export type SignatureResultCallback = (
signatureResult: SignatureSuccess | TransactionError, signatureResult: SignatureResult,
context: Context, context: Context,
) => void; ) => void;
export type RootChangeCallback = (root: number) => void; export type RootChangeCallback = (root: number) => void;
export type SignatureSuccess = { export type TransactionError = object;
Ok: null; export type SignatureResult = {
}; err: TransactionError | null;
export type TransactionError = {
Err: object;
}; };
export type Inflation = { export type Inflation = {

View File

@ -19,7 +19,7 @@ declare module '@solana/web3.js' {
constructor( constructor(
value: number | string | Buffer | Uint8Array | Array<number>, value: number | string | Buffer | Uint8Array | Array<number>,
): PublicKey; ): PublicKey;
static isPublicKey(o: Object): boolean; static isPublicKey(o: {}): boolean;
static createWithSeed( static createWithSeed(
fromPublicKey: PublicKey, fromPublicKey: PublicKey,
seed: string, seed: string,
@ -63,7 +63,7 @@ declare module '@solana/web3.js' {
declare export type SignatureStatus = { declare export type SignatureStatus = {
slot: number, slot: number,
status: SignatureSuccess | TransactionError, err: TransactionError | null,
confirmations: number | null, confirmations: number | null,
}; };
@ -102,8 +102,8 @@ declare module '@solana/web3.js' {
fee: number, fee: number,
preBalances: Array<number>, preBalances: Array<number>,
postBalances: Array<number>, postBalances: Array<number>,
status: SignatureSuccess | TransactionError | null, err: TransactionError | null,
}, } | null,
}>, }>,
}; };
@ -139,16 +139,14 @@ declare module '@solana/web3.js' {
) => void; ) => void;
declare type SlotChangeCallback = (slotInfo: SlotInfo) => void; declare type SlotChangeCallback = (slotInfo: SlotInfo) => void;
declare type SignatureResultCallback = ( declare type SignatureResultCallback = (
signatureResult: SignatureSuccess | TransactionError, signatureResult: SignatureResult,
context: Context, context: Context,
) => void; ) => void;
declare type RootChangeCallback = (root: number) => void; declare type RootChangeCallback = (root: number) => void;
declare export type SignatureSuccess = {| declare export type TransactionError = {};
Ok: null, declare export type SignatureResult = {|
|}; err: TransactionError | null,
declare export type TransactionError = {|
Err: Object,
|}; |};
declare export type Inflation = { declare export type Inflation = {
@ -331,10 +329,7 @@ declare module '@solana/web3.js' {
layout: typeof BufferLayout, layout: typeof BufferLayout,
|}; |};
declare export function encodeData( declare export function encodeData(type: InstructionType, fields: {}): Buffer;
type: InstructionType,
fields: Object,
): Buffer;
// === src/transaction.js === // === src/transaction.js ===
declare export type TransactionSignature = string; declare export type TransactionSignature = string;

View File

@ -203,13 +203,15 @@ const GetEpochScheduleResult = struct({
firstNormalSlot: 'number', firstNormalSlot: 'number',
}); });
/**
* Transaction error or null
*/
const TransactionErrorResult = struct.union(['null', 'object']);
/** /**
* Signature status for a transaction * Signature status for a transaction
*/ */
const SignatureStatusResult = struct.union([ const SignatureStatusResult = struct({err: TransactionErrorResult});
struct({Ok: 'null'}),
struct({Err: 'object'}),
]);
/** /**
* Version info for a node * Version info for a node
@ -241,8 +243,8 @@ type ConfirmedBlock = {
fee: number, fee: number,
preBalances: Array<number>, preBalances: Array<number>,
postBalances: Array<number>, postBalances: Array<number>,
status?: SignatureSuccess | TransactionError, err: {} | null,
}, } | null,
}>, }>,
rewards: Array<{ rewards: Array<{
pubkey: string, pubkey: string,
@ -483,10 +485,10 @@ const GetSignatureStatusesRpcResult = jsonRpcResultAndContext(
struct.array([ struct.array([
struct.union([ struct.union([
'null', 'null',
struct({ struct.pick({
slot: 'number', slot: 'number',
confirmations: struct.union(['number', 'null']), confirmations: struct.union(['number', 'null']),
status: SignatureStatusResult, err: TransactionErrorResult,
}), }),
]), ]),
]), ]),
@ -543,8 +545,8 @@ export const GetConfirmedBlockRpcResult = jsonRpcResult(
}), }),
meta: struct.union([ meta: struct.union([
'null', 'null',
struct({ struct.pick({
status: struct.union(['null', SignatureStatusResult]), err: TransactionErrorResult,
fee: 'number', fee: 'number',
preBalances: struct.array(['number']), preBalances: struct.array(['number']),
postBalances: struct.array(['number']), postBalances: struct.array(['number']),
@ -685,7 +687,7 @@ type SlotSubscriptionInfo = {
* Callback function for signature notifications * Callback function for signature notifications
*/ */
export type SignatureResultCallback = ( export type SignatureResultCallback = (
signatureResult: SignatureSuccess | TransactionError, signatureResult: SignatureResult,
context: Context, context: Context,
) => void; ) => void;
@ -712,22 +714,20 @@ type RootSubscriptionInfo = {
}; };
/** /**
* Signature status: Success * Signature result
* *
* @typedef {Object} SignatureSuccess * @typedef {Object} SignatureResult
*/ */
export type SignatureSuccess = {| export type SignatureResult = {|
Ok: null, err: TransactionError | null,
|}; |};
/** /**
* Signature status: TransactionError * Transaction error
* *
* @typedef {Object} TransactionError * @typedef {Object} TransactionError
*/ */
export type TransactionError = {| export type TransactionError = {};
Err: Object,
|};
/** /**
* Signature status * Signature status
@ -735,12 +735,12 @@ export type TransactionError = {|
* @typedef {Object} SignatureStatus * @typedef {Object} SignatureStatus
* @property {number} slot when the transaction was processed * @property {number} slot when the transaction was processed
* @property {number | null} confirmations the number of blocks that have been confirmed and voted on in the fork containing `slot` (TODO) * @property {number | null} confirmations the number of blocks that have been confirmed and voted on in the fork containing `slot` (TODO)
* @property {SignatureStatus | TransactionError} status success or error * @property {TransactionError | null} err error, if any
*/ */
export type SignatureStatus = { export type SignatureStatus = {
slot: number, slot: number,
confirmations: number | null, confirmations: number | null,
status: SignatureSuccess | TransactionError, err: TransactionError | null,
}; };
/** /**

View File

@ -39,7 +39,7 @@ export async function sendAndConfirmRawTransaction(
} }
} }
if (status && status.status && 'Ok' in status.status) { if (status && !status.err) {
return signature; return signature;
} }

View File

@ -66,9 +66,16 @@ async function _sendAndConfirmTransaction(
await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND); await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND);
} }
if (status && 'Ok' in status.status) { if (status) {
break; if (!status.err) {
break;
} else if (!('AccountInUse' in status.err)) {
throw new Error(
`Transaction ${signature} failed (${JSON.stringify(status)})`,
);
}
} }
if (--sendRetries <= 0) { if (--sendRetries <= 0) {
const duration = (Date.now() - start) / 1000; const duration = (Date.now() - start) / 1000;
throw new Error( throw new Error(
@ -78,12 +85,6 @@ async function _sendAndConfirmTransaction(
); );
} }
if (status && status.status.Err && !('AccountInUse' in status.status.Err)) {
throw new Error(
`Transaction ${signature} failed (${JSON.stringify(status)})`,
);
}
// Retry in 0..100ms to try to avoid another AccountInUse collision // Retry in 0..100ms to try to avoid another AccountInUse collision
await sleep(Math.random() * 100); await sleep(Math.random() * 100);
} }

View File

@ -117,6 +117,7 @@ test('get program accounts', async () => {
slot: 0, slot: 0,
confirmations: 11, confirmations: 11,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
], ],
}, },
@ -161,6 +162,7 @@ test('get program accounts', async () => {
slot: 0, slot: 0,
confirmations: 11, confirmations: 11,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
], ],
}, },
@ -627,6 +629,7 @@ test('get confirmed block', async () => {
postBalances: [499260347380, 15298080, 1, 1, 1], postBalances: [499260347380, 15298080, 1, 1, 1],
preBalances: [499260357380, 15298080, 1, 1, 1], preBalances: [499260357380, 15298080, 1, 1, 1],
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
transaction: { transaction: {
message: { message: {
@ -906,6 +909,7 @@ test('request airdrop - max commitment', async () => {
slot: 0, slot: 0,
confirmations: null, confirmations: null,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
], ],
}, },
@ -1100,6 +1104,7 @@ test('transaction', async () => {
slot: 0, slot: 0,
confirmations: 11, confirmations: 11,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
], ],
}, },
@ -1118,7 +1123,7 @@ test('transaction', async () => {
return; return;
} }
expect(response.status).toEqual({Ok: null}); expect(response.err).toBeNull();
expect(response.slot).toBeGreaterThanOrEqual(0); expect(response.slot).toBeGreaterThanOrEqual(0);
expect(responseConfirmations).toBeGreaterThan(0); expect(responseConfirmations).toBeGreaterThan(0);
@ -1147,6 +1152,7 @@ test('transaction', async () => {
slot: 0, slot: 0,
confirmations: 11, confirmations: 11,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
null, null,
], ],
@ -1168,7 +1174,7 @@ test('transaction', async () => {
} }
expect(firstResponse.slot).toBeGreaterThanOrEqual(response.slot); expect(firstResponse.slot).toBeGreaterThanOrEqual(response.slot);
expect(firstResponse.status).toEqual(response.status); expect(firstResponse.err).toEqual(response.err);
if (typeof firstResponse.confirmations !== 'number') { if (typeof firstResponse.confirmations !== 'number') {
expect(typeof firstResponse.confirmations).toEqual('number'); expect(typeof firstResponse.confirmations).toEqual('number');
@ -1279,7 +1285,7 @@ test('multi-instruction transaction', async () => {
const response = (await connection.getSignatureStatus(signature)).value; const response = (await connection.getSignatureStatus(signature)).value;
if (response !== null) { if (response !== null) {
expect(typeof response.slot).toEqual('number'); expect(typeof response.slot).toEqual('number');
expect(response.status).toEqual({Ok: null}); expect(response.err).toBeNull();
} else { } else {
expect(response).not.toBeNull(); expect(response).not.toBeNull();
} }

View File

@ -39,7 +39,8 @@ test('verify getConfirmedBlock', () => {
fee: 0, fee: 0,
preBalances: [100000, 100000, 1, 1, 1], preBalances: [100000, 100000, 1, 1, 1],
postBalances: [99877, 100123, 1, 1, 1], postBalances: [99877, 100123, 1, 1, 1],
status: {Ok: 'null'}, status: {Ok: null},
err: null,
}, },
}, },
{ {
@ -48,7 +49,8 @@ test('verify getConfirmedBlock', () => {
fee: 0, fee: 0,
preBalances: [100000, 100000, 1, 1, 1], preBalances: [100000, 100000, 1, 1, 1],
postBalances: [99544, 100456, 1, 1, 1], postBalances: [99544, 100456, 1, 1, 1],
status: {Ok: 'null'}, status: {Ok: null},
err: null,
}, },
}, },
], ],

View File

@ -165,6 +165,7 @@ test('transaction-payer', async () => {
slot: 0, slot: 0,
confirmations: 11, confirmations: 11,
status: {Ok: null}, status: {Ok: null},
err: null,
}, },
], ],
}, },
@ -173,7 +174,7 @@ test('transaction-payer', async () => {
const {value} = await connection.getSignatureStatus(signature); const {value} = await connection.getSignatureStatus(signature);
if (value !== null) { if (value !== null) {
expect(typeof value.slot).toEqual('number'); expect(typeof value.slot).toEqual('number');
expect(value.status).toEqual({Ok: null}); expect(value.err).toBeNull();
} else { } else {
expect(value).not.toBeNull(); expect(value).not.toBeNull();
} }