Skip to content

Commit

Permalink
Merge pull request #698 from 0xs34n/feat/0.12.1/reverted
Browse files Browse the repository at this point in the history
feat: 0.12.1
  • Loading branch information
tabaktoni authored Aug 5, 2023
2 parents 3bd7571 + c1f2d47 commit 42120b9
Show file tree
Hide file tree
Showing 13 changed files with 570 additions and 271 deletions.
14 changes: 5 additions & 9 deletions __tests__/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
Account,
Contract,
DeclareDeployUDCResponse,
DeployTransactionReceiptResponse,
Provider,
TransactionStatus,
TransactionType,
cairo,
contractClassResponseToLegacyCompiledContract,
Expand Down Expand Up @@ -338,9 +338,7 @@ describe('deploy and test Wallet', () => {
calldata: [erc20.address, '10', '0'],
});

await provider.waitForTransaction(transaction_hash, {
successStates: [TransactionStatus.ACCEPTED_ON_L2],
});
await provider.waitForTransaction(transaction_hash);
});

test('read balance of wallet after transfer', async () => {
Expand Down Expand Up @@ -379,9 +377,7 @@ describe('deploy and test Wallet', () => {
},
]);

await provider.waitForTransaction(transaction_hash, {
successStates: [TransactionStatus.ACCEPTED_ON_L2],
});
await provider.waitForTransaction(transaction_hash);

const response = await dapp.get_number(account.address);
expect(toBigInt(response.number as string).toString()).toStrictEqual('57');
Expand Down Expand Up @@ -552,7 +548,7 @@ describe('deploy and test Wallet', () => {

// check pre-calculated address
const txReceipt = await provider.waitForTransaction(deployment.transaction_hash);
const udcEvent = parseUDCEvent(txReceipt);
const udcEvent = parseUDCEvent(txReceipt as DeployTransactionReceiptResponse);
expect(cleanHex(deployment.contract_address[0])).toBe(cleanHex(udcEvent.contract_address));
});

Expand All @@ -573,7 +569,7 @@ describe('deploy and test Wallet', () => {

// check pre-calculated address
const txReceipt = await provider.waitForTransaction(deployment.transaction_hash);
const udcEvent = parseUDCEvent(txReceipt);
const udcEvent = parseUDCEvent(txReceipt as DeployTransactionReceiptResponse);
expect(cleanHex(deployment.contract_address[0])).toBe(cleanHex(udcEvent.contract_address));
});

Expand Down
59 changes: 33 additions & 26 deletions __tests__/schemas/rpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,41 @@
"$id": "rpcSchemas",
"definitions": {
"GetSyncingStatsResponse": {
"type": "object",
"properties": {
"current_block_hash": {
"type": "string"
},
"current_block_num": {
"type": "string"
},
"highest_block_hash": {
"type": "string"
"oneOf": [
{
"type": "object",
"properties": {
"current_block_hash": {
"type": "string"
},
"current_block_num": {
"type": "number"
},
"highest_block_hash": {
"type": "string"
},
"highest_block_num": {
"type": "number"
},
"starting_block_hash": {
"type": "string"
},
"starting_block_num": {
"type": "number"
}
},
"required": [
"current_block_hash",
"current_block_num",
"highest_block_hash",
"highest_block_num",
"starting_block_hash",
"starting_block_num"
]
},
"highest_block_num": {
"type": "string"
},
"starting_block_hash": {
"type": "string"
},
"starting_block_num": {
"type": "string"
{
"type": "boolean"
}
},
"required": [
"current_block_hash",
"current_block_num",
"highest_block_hash",
"highest_block_num",
"starting_block_hash",
"starting_block_num"
]
},
"StarknetEmittedEvent": {
Expand Down
3 changes: 2 additions & 1 deletion src/account/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
DeployAccountContractTransaction,
DeployContractResponse,
DeployContractUDCResponse,
DeployTransactionReceiptResponse,
Details,
EstimateFee,
EstimateFeeAction,
Expand Down Expand Up @@ -399,7 +400,7 @@ export class Account extends Provider implements AccountInterface {
): Promise<DeployContractUDCResponse> {
const deployTx = await this.deploy(payload, details);
const txReceipt = await this.waitForTransaction(deployTx.transaction_hash);
return parseUDCEvent(txReceipt);
return parseUDCEvent(txReceipt as DeployTransactionReceiptResponse);
}

public async declareAndDeploy(
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export { IS_BROWSER } from './utils/encode';

export const HEX_STR_TRANSACTION_VERSION_1 = '0x1';
export const HEX_STR_TRANSACTION_VERSION_2 = '0x2';

export const ZERO = 0n;
export const MASK_250 = 2n ** 250n - 1n; // 2 ** 250 - 1
export const MASK_251 = 2n ** 251n;
Expand Down
96 changes: 53 additions & 43 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { StarknetChainId } from '../constants';
import {
HEX_STR_TRANSACTION_VERSION_1,
HEX_STR_TRANSACTION_VERSION_2,
StarknetChainId,
} from '../constants';
import {
AccountInvocationItem,
AccountInvocations,
BigNumberish,
BlockIdentifier,
BlockTag,
Call,
CallContractResponse,
ContractClassResponse,
Expand All @@ -19,27 +24,24 @@ import {
Invocation,
InvocationsDetailsWithNonce,
InvokeFunctionResponse,
LegacyContractClass,
RPC,
RpcProviderOptions,
SIMULATION_FLAG,
SierraContractClass,
SimulateTransactionResponse,
TransactionStatus,
TransactionType,
getEstimateFeeBulkOptions,
getSimulateTransactionOptions,
waitForTransactionOptions,
} from '../types';
import {
SimulationFlag,
TransactionExecutionStatus,
TransactionFinalityStatus,
} from '../types/api/rpc';
import { CallData } from '../utils/calldata';
import { isSierra } from '../utils/contract';
import { pascalToSnake } from '../utils/encode';
import fetch from '../utils/fetchPonyfill';
import {
getSelectorFromName,
getVersionsByType,
transactionVersion,
transactionVersion_2,
} from '../utils/hash';
import { getSelectorFromName, getVersionsByType } from '../utils/hash';
import { stringify } from '../utils/json';
import { toHex, toStorageKey } from '../utils/num';
import { wait } from '../utils/provider';
Expand All @@ -54,7 +56,7 @@ import { Block } from './utils';
// Note that pending support is disabled by default and must be enabled by setting poll-pending=true in the configuration options.
const defaultOptions = {
headers: { 'Content-Type': 'application/json' },
blockIdentifier: 'latest',
blockIdentifier: BlockTag.pending,
retries: 200,
};

Expand Down Expand Up @@ -345,7 +347,7 @@ export class RpcProvider implements ProviderInterface {
entry_points_by_type: contract.entry_points_by_type,
abi: contract.abi,
},
version: toHex(transactionVersion),
version: HEX_STR_TRANSACTION_VERSION_1,
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
Expand All @@ -363,7 +365,7 @@ export class RpcProvider implements ProviderInterface {
abi: contract.abi,
},
compiled_class_hash: compiledClassHash || '',
version: toHex(transactionVersion_2),
version: HEX_STR_TRANSACTION_VERSION_2,
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
Expand Down Expand Up @@ -434,15 +436,17 @@ export class RpcProvider implements ProviderInterface {
}

public async waitForTransaction(txHash: string, options?: waitForTransactionOptions) {
const errorStates = [TransactionStatus.REJECTED, TransactionStatus.NOT_RECEIVED];
let { retries } = this;
let onchain = false;
let isErrorState = false;
// eslint-disable-next-line no-undef-init
let txReceipt: any = {};

const retryInterval = options?.retryInterval ?? 8000;
const successStates = options?.successStates ?? [
TransactionStatus.ACCEPTED_ON_L1,
TransactionStatus.ACCEPTED_ON_L2,
const retryInterval = options?.retryInterval ?? 5000;
const errorStates: any = options?.errorStates ?? [TransactionExecutionStatus.REVERTED];
const successStates: any = options?.successStates ?? [
TransactionExecutionStatus.SUCCEEDED,
TransactionFinalityStatus.ACCEPTED_ON_L1,
TransactionFinalityStatus.ACCEPTED_ON_L2,
];

while (!onchain) {
Expand All @@ -452,21 +456,28 @@ export class RpcProvider implements ProviderInterface {
// eslint-disable-next-line no-await-in-loop
txReceipt = await this.getTransactionReceipt(txHash);

if (!('status' in txReceipt)) {
const error = new Error('transaction status');
// TODO: Hotfix until Pathfinder release fixed casing
const executionStatus = pascalToSnake(txReceipt.execution_status);
const finalityStatus = pascalToSnake(txReceipt.finality_status);

if (!executionStatus || !finalityStatus) {
// Transaction is potentially REJECTED or NOT_RECEIVED but RPC doesn't have dose statuses
// so we will retry '{ retries }' times
const error = new Error('waiting for transaction status');
throw error;
}

if (txReceipt.status && successStates.includes(txReceipt.status)) {
if (successStates.includes(executionStatus) || successStates.includes(finalityStatus)) {
onchain = true;
} else if (txReceipt.status && errorStates.includes(txReceipt.status)) {
const message = txReceipt.status;
const error = new Error(message) as Error & { response: any };
} else if (errorStates.includes(executionStatus) || errorStates.includes(finalityStatus)) {
const message = `${executionStatus}: ${finalityStatus}: ${txReceipt.revert_reason}`;
const error = new Error(message) as Error & { response: RPC.TransactionReceipt };
error.response = txReceipt;
isErrorState = true;
throw error;
}
} catch (error: unknown) {
if (error instanceof Error && errorStates.includes(error.message as TransactionStatus)) {
} catch (error) {
if (error instanceof Error && isErrorState) {
throw error;
}

Expand Down Expand Up @@ -531,18 +542,19 @@ export class RpcProvider implements ProviderInterface {
{
blockIdentifier = this.blockIdentifier,
skipValidate = false,
skipExecute = false,
skipExecute = false, // @deprecated
skipFeeCharge = true, // Pathfinder currently does not support `starknet_simulateTransactions` without `SKIP_FEE_CHARGE` simulation flag being set. This will become supported in a future release
}: getSimulateTransactionOptions
): Promise<SimulateTransactionResponse> {
const block_id = new Block(blockIdentifier).identifier;

const simulationFlags = [];
if (skipValidate) simulationFlags.push(SIMULATION_FLAG.SKIP_VALIDATE);
if (skipExecute) simulationFlags.push(SIMULATION_FLAG.SKIP_EXECUTE);
if (skipValidate) simulationFlags.push(SimulationFlag.SKIP_VALIDATE);
if (skipExecute || skipFeeCharge) simulationFlags.push(SimulationFlag.SKIP_FEE_CHARGE);

return this.fetchEndpoint('starknet_simulateTransaction', {
return this.fetchEndpoint('starknet_simulateTransactions', {
block_id,
transactions: invocations.map((it) => this.buildTransaction(it)), // TODO: Pathfinder 0.5.6 bug, should be transaction
transactions: invocations.map((it) => this.buildTransaction(it)),
simulation_flags: simulationFlags,
}).then(this.responseParser.parseSimulateTransactionResponse);
}
Expand All @@ -558,7 +570,7 @@ export class RpcProvider implements ProviderInterface {
public buildTransaction(
invocation: AccountInvocationItem,
versionType?: 'fee' | 'transaction'
): RPC.BroadcastedTransaction {
): RPC.BaseTransaction {
const defaultVersions = getVersionsByType(versionType);
const details = {
signature: signatureToHexArray(invocation.signature),
Expand All @@ -571,32 +583,30 @@ export class RpcProvider implements ProviderInterface {
type: RPC.TransactionType.INVOKE, // Diff between sequencer and rpc invoke type
sender_address: invocation.contractAddress,
calldata: CallData.toHex(invocation.calldata),
version: toHex(invocation.version || defaultVersions.v1),
version: toHex(invocation.version || defaultVersions.v1) as any, // HEX_STR_TRANSACTION_VERSION_1, // as any HOTFIX TODO: Resolve spec version
...details,
};
}
if (invocation.type === RPC.TransactionType.DECLARE) {
if (invocation.type === TransactionType.DECLARE) {
if (!isSierra(invocation.contract)) {
const legacyContract = invocation.contract as LegacyContractClass;
return {
type: invocation.type,
contract_class: legacyContract,
contract_class: invocation.contract,
sender_address: invocation.senderAddress,
version: toHex(invocation.version || defaultVersions.v1),
version: toHex(invocation.version || defaultVersions.v1) as any, // HEX_STR_TRANSACTION_VERSION_1, // as any HOTFIX TODO: Resolve spec version
...details,
};
}
const sierraContract = invocation.contract as SierraContractClass;
return {
// compiled_class_hash
type: invocation.type,
contract_class: {
...sierraContract,
sierra_program: decompressProgram(sierraContract.sierra_program),
...invocation.contract,
sierra_program: decompressProgram(invocation.contract.sierra_program),
},
compiled_class_hash: invocation.compiledClassHash || '',
sender_address: invocation.senderAddress,
version: toHex(invocation.version || defaultVersions.v2),
version: toHex(invocation.version || defaultVersions.v2) as any, // HEX_STR_TRANSACTION_VERSION_2, // as any HOTFIX TODO: Resolve spec version
...details,
};
}
Expand Down
Loading

0 comments on commit 42120b9

Please sign in to comment.