Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 53 additions & 26 deletions src/api/controllers/db-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ export async function getRosettaBlockFromDataStore(

export async function getUnanchoredTxsFromDataStore(db: PgStore): Promise<Transaction[]> {
const dbTxs = await db.getUnanchoredTxs();
const parsedTxs = dbTxs.txs.map(dbTx => parseDbTx(dbTx));
const parsedTxs = dbTxs.txs.map(dbTx => parseDbTx(dbTx, false));
return parsedTxs;
}

Expand Down Expand Up @@ -864,6 +864,7 @@ export async function getRosettaTransactionFromDataStore(
interface GetTxArgs {
txId: string;
includeUnanchored: boolean;
excludeFunctionArgs: boolean;
}

interface GetTxFromDbTxArgs extends GetTxArgs {
Expand All @@ -878,6 +879,7 @@ interface GetTxsWithEventsArgs extends GetTxsArgs {
interface GetTxsArgs {
txIds: string[];
includeUnanchored: boolean;
excludeFunctionArgs: boolean;
}

interface GetTxWithEventsArgs extends GetTxArgs {
Expand Down Expand Up @@ -905,7 +907,10 @@ function parseDbBaseTx(dbTx: DbTx | DbMempoolTx): BaseTransaction {
return tx;
}

function parseDbTxTypeMetadata(dbTx: DbTx | DbMempoolTx): TransactionMetadata {
function parseDbTxTypeMetadata(
dbTx: DbTx | DbMempoolTx,
excludeFunctionArgs: boolean
): TransactionMetadata {
switch (dbTx.type_id) {
case DbTxTypeId.TokenTransfer: {
const metadata: TokenTransferTransactionMetadata = {
Expand Down Expand Up @@ -965,7 +970,7 @@ function parseDbTxTypeMetadata(dbTx: DbTx | DbMempoolTx): TransactionMetadata {
return metadata;
}
case DbTxTypeId.ContractCall: {
return parseContractCallMetadata(dbTx);
return parseContractCallMetadata(dbTx, excludeFunctionArgs);
}
case DbTxTypeId.PoisonMicroblock: {
const metadata: PoisonMicroblockTransactionMetadata = {
Expand Down Expand Up @@ -1052,7 +1057,10 @@ function parseDbTxTypeMetadata(dbTx: DbTx | DbMempoolTx): TransactionMetadata {
}
}

export function parseContractCallMetadata(tx: BaseTx): ContractCallTransactionMetadata {
export function parseContractCallMetadata(
tx: BaseTx,
excludeFunctionArgs: boolean
): ContractCallTransactionMetadata {
const contractId = unwrapOptional(
tx.contract_call_contract_id,
() => 'Unexpected nullish contract_call_contract_id'
Expand All @@ -1063,6 +1071,7 @@ export function parseContractCallMetadata(tx: BaseTx): ContractCallTransactionMe
);
let functionAbi: ClarityAbiFunction | undefined;
const abi = tx.abi;

if (abi) {
const contractAbi: ClarityAbi = JSON.parse(abi);
functionAbi = contractAbi.functions.find(fn => fn.name === functionName);
Expand All @@ -1071,30 +1080,42 @@ export function parseContractCallMetadata(tx: BaseTx): ContractCallTransactionMe
}
}

const functionArgs = tx.contract_call_function_args
? decodeClarityValueList(tx.contract_call_function_args).map((c, fnArgIndex) => {
const functionArgAbi = functionAbi
? functionAbi.args[fnArgIndex++]
: { name: '', type: undefined };
const contractCall: {
contract_id: string;
function_name: string;
function_signature: string;
function_args?: {
hex: string;
repr: string;
name: string;
type: string;
}[];
} = {
contract_id: contractId,
function_name: functionName,
function_signature: functionAbi ? abiFunctionToString(functionAbi) : '',
};

// Only process function_args if not excluded
if (!excludeFunctionArgs && tx.contract_call_function_args) {
contractCall.function_args = decodeClarityValueList(tx.contract_call_function_args).map(
(c, idx) => {
const functionArgAbi = functionAbi ? functionAbi.args[idx] : { name: '', type: undefined };
return {
hex: c.hex,
repr: c.repr,
name: functionArgAbi.name,
type: functionArgAbi.type
name: functionArgAbi?.name || '',
type: functionArgAbi?.type
? getTypeString(functionArgAbi.type)
: decodeClarityValueToTypeName(c.hex),
};
})
: undefined;
}
);
}

const metadata: ContractCallTransactionMetadata = {
tx_type: 'contract_call',
contract_call: {
contract_id: contractId,
function_name: functionName,
function_signature: functionAbi ? abiFunctionToString(functionAbi) : '',
function_args: functionArgs,
},
contract_call: contractCall,
};
return metadata;
}
Expand Down Expand Up @@ -1154,21 +1175,24 @@ function parseDbAbstractMempoolTx(
return abstractMempoolTx;
}

export function parseDbTx(dbTx: DbTx): Transaction {
export function parseDbTx(dbTx: DbTx, excludeFunctionArgs: boolean): Transaction {
const baseTx = parseDbBaseTx(dbTx);
const abstractTx = parseDbAbstractTx(dbTx, baseTx);
const txMetadata = parseDbTxTypeMetadata(dbTx);
const txMetadata = parseDbTxTypeMetadata(dbTx, excludeFunctionArgs);
const result: Transaction = {
...abstractTx,
...txMetadata,
};
return result;
}

export function parseDbMempoolTx(dbMempoolTx: DbMempoolTx): MempoolTransaction {
export function parseDbMempoolTx(
dbMempoolTx: DbMempoolTx,
excludeFunctionArgs: boolean
): MempoolTransaction {
const baseTx = parseDbBaseTx(dbMempoolTx);
const abstractTx = parseDbAbstractMempoolTx(dbMempoolTx, baseTx);
const txMetadata = parseDbTxTypeMetadata(dbMempoolTx);
const txMetadata = parseDbTxTypeMetadata(dbMempoolTx, excludeFunctionArgs);
const result: MempoolTransaction = {
...abstractTx,
...txMetadata,
Expand All @@ -1189,7 +1213,9 @@ export async function getMempoolTxsFromDataStore(
return [];
}

const parsedMempoolTxs = mempoolTxsQuery.map(tx => parseDbMempoolTx(tx));
const parsedMempoolTxs = mempoolTxsQuery.map(tx =>
parseDbMempoolTx(tx, args.excludeFunctionArgs)
);

return parsedMempoolTxs;
}
Expand All @@ -1211,7 +1237,7 @@ async function getTxsFromDataStore(
}

// parsing txQuery
const parsedTxs = txQuery.map(tx => parseDbTx(tx));
const parsedTxs = txQuery.map(tx => parseDbTx(tx, args.excludeFunctionArgs));

// incase transaction events are requested
if ('eventLimit' in args) {
Expand Down Expand Up @@ -1261,7 +1287,7 @@ export async function getTxFromDataStore(
dbTx = txQuery.result;
}

const parsedTx = parseDbTx(dbTx);
const parsedTx = parseDbTx(dbTx, args.excludeFunctionArgs);

// If tx events are requested
if ('eventLimit' in args) {
Expand Down Expand Up @@ -1315,6 +1341,7 @@ export async function searchTxs(
const mempoolTxsQuery = await getMempoolTxsFromDataStore(db, {
txIds: mempoolTxs,
includeUnanchored: args.includeUnanchored,
excludeFunctionArgs: args.excludeFunctionArgs,
});

// merging found mempool transaction in found transactions object
Expand Down
13 changes: 11 additions & 2 deletions src/api/routes/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
PrincipalSchema,
UnanchoredParamSchema,
UntilBlockSchema,
ExcludeFunctionArgsParamSchema,
} from '../schemas/params';
import {
AddressBalance,
Expand Down Expand Up @@ -290,6 +291,7 @@ export const AddressRoutes: FastifyPluginAsync<
),
unanchored: UnanchoredParamSchema,
until_block: UntilBlockSchema,
exclude_function_args: ExcludeFunctionArgsParamSchema,
}),
response: {
200: AddressTransactionsListResponseSchema,
Expand All @@ -302,6 +304,7 @@ export const AddressRoutes: FastifyPluginAsync<
const untilBlock = parseUntilBlockQuery(req.query.until_block, req.query.unanchored);
const limit = getPagingQueryLimit(ResourceType.Tx, req.query.limit);
const offset = req.query.offset ?? 0;
const excludeFunctionArgs = req.query.exclude_function_args ?? false;

const response = await fastify.db.sqlTransaction(async sql => {
const blockParams = getBlockParams(req.query.height, req.query.unanchored);
Expand All @@ -327,7 +330,7 @@ export const AddressRoutes: FastifyPluginAsync<
blockHeight,
atSingleBlock,
});
const results = txResults.map(dbTx => parseDbTx(dbTx));
const results = txResults.map(dbTx => parseDbTx(dbTx, excludeFunctionArgs));
const response = { limit, offset, total, results };
return response;
});
Expand Down Expand Up @@ -376,6 +379,7 @@ export const AddressRoutes: FastifyPluginAsync<
txId: results.tx.tx_id,
dbTx: results.tx,
includeUnanchored: false,
excludeFunctionArgs: false,
});
if (!txQuery.found) {
throw new Error('unexpected tx not found -- fix tx enumeration query');
Expand Down Expand Up @@ -468,6 +472,7 @@ export const AddressRoutes: FastifyPluginAsync<
txId: entry.tx.tx_id,
dbTx: entry.tx,
includeUnanchored: blockParams.includeUnanchored ?? false,
excludeFunctionArgs: false,
});
if (!txQuery.found) {
throw new Error('unexpected tx not found -- fix tx enumeration query');
Expand Down Expand Up @@ -671,6 +676,7 @@ export const AddressRoutes: FastifyPluginAsync<
limit: LimitParam(ResourceType.Tx),
offset: OffsetParam(),
unanchored: UnanchoredParamSchema,
exclude_function_args: ExcludeFunctionArgsParamSchema,
}),
response: {
200: PaginatedResponse(MempoolTransactionSchema, {
Expand All @@ -690,13 +696,16 @@ export const AddressRoutes: FastifyPluginAsync<
);
}
const includeUnanchored = req.query.unanchored ?? false;
const excludeFunctionArgs = req.query.exclude_function_args ?? false;
const { results: txResults, total } = await fastify.db.getMempoolTxList({
offset,
limit,
address,
includeUnanchored,
});
const results: MempoolTransaction[] = txResults.map(tx => parseDbMempoolTx(tx));
const results: MempoolTransaction[] = txResults.map(tx =>
parseDbMempoolTx(tx, excludeFunctionArgs)
);
const response = { limit, offset, total, results };
await reply.send(response);
}
Expand Down
1 change: 1 addition & 0 deletions src/api/routes/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export const BlockRoutes: FastifyPluginAsync<
if (!block.found) {
throw new NotFoundError(`cannot find block by hash`);
}

await reply.send(block.result);
}
);
Expand Down
8 changes: 4 additions & 4 deletions src/api/routes/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const SearchRoutes: FastifyPluginAsync<
},
};
if (includeMetadata) {
txResult.metadata = parseDbTx(txData);
txResult.metadata = parseDbTx(txData, false);
}
return { found: true, result: txResult };
} else if (queryResult.result.entity_type === 'mempool_tx_id') {
Expand All @@ -127,7 +127,7 @@ export const SearchRoutes: FastifyPluginAsync<
},
};
if (includeMetadata) {
txResult.metadata = parseDbMempoolTx(txData);
txResult.metadata = parseDbMempoolTx(txData, false);
}
return { found: true, result: txResult };
} else {
Expand Down Expand Up @@ -176,7 +176,7 @@ export const SearchRoutes: FastifyPluginAsync<
},
};
if (includeMetadata) {
contractResult.metadata = parseDbTx(txData);
contractResult.metadata = parseDbTx(txData, false);
}
return { found: true, result: contractResult };
} else {
Expand All @@ -191,7 +191,7 @@ export const SearchRoutes: FastifyPluginAsync<
},
};
if (includeMetadata) {
contractResult.metadata = parseDbMempoolTx(txData);
contractResult.metadata = parseDbMempoolTx(txData, false);
}
return { found: true, result: contractResult };
}
Expand Down
6 changes: 3 additions & 3 deletions src/api/routes/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const TokenRoutes: FastifyPluginAsync<
if (includeTxMetadata && result.tx) {
return {
...parsedNftData,
tx: parseDbTx(result.tx),
tx: parseDbTx(result.tx, false),
};
}
return { ...parsedNftData, tx_id: result.nft_holding_info.tx_id };
Expand Down Expand Up @@ -225,7 +225,7 @@ export const TokenRoutes: FastifyPluginAsync<
if (includeTxMetadata && result.tx) {
return {
...parsedNftData,
tx: parseDbTx(result.tx),
tx: parseDbTx(result.tx, false),
};
}
return { ...parsedNftData, tx_id: result.nft_event.tx_id };
Expand Down Expand Up @@ -331,7 +331,7 @@ export const TokenRoutes: FastifyPluginAsync<
if (includeTxMetadata && result.tx) {
return {
...parsedNftData,
tx: parseDbTx(result.tx),
tx: parseDbTx(result.tx, false),
};
}
return { ...parsedNftData, tx_id: result.nft_event.tx_id };
Expand Down
Loading