Skip to content

Commit

Permalink
refactor(bungee): besu, ethereum and fabric strategy error handling a…
Browse files Browse the repository at this point in the history
…nd input validation

Signed-off-by: Carlos Amaro <[email protected]>
  • Loading branch information
LordKubaya committed Jun 14, 2024
1 parent ce95421 commit f0e959b
Show file tree
Hide file tree
Showing 3 changed files with 457 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export class StrategyBesu implements ObtainLedgerStrategy {
besuApi = new BesuApi(config);
} else {
throw new Error(
`${StrategyBesu.CLASS_NAME}#generateLedgerStates: networkDetails must have either connector or connectorApiPath`,
`${fn} networkDetails must have either connector or connectorApiPath`,
);
}
const connectorOrApiClient = connector ? connector : besuApi;
const connectorOrApiClient = networkDetails.connector ? connector : besuApi;
if (!connectorOrApiClient) {
throw new InternalServerError(`${fn} got neither connector nor BesuAPI`);
}
Expand All @@ -81,8 +81,7 @@ export class StrategyBesu implements ObtainLedgerStrategy {
const { transactions, values, blocks } = await this.getAllInfoByKey(
assetKey,
networkDetails,
connector,
besuApi,
connectorOrApiClient,
);

const state = new State(assetKey, values, transactions);
Expand Down Expand Up @@ -133,8 +132,7 @@ export class StrategyBesu implements ObtainLedgerStrategy {
async getAllInfoByKey(
key: string,
networkDetails: BesuNetworkDetails,
connector: PluginLedgerConnectorBesu | undefined,
api: BesuApi | undefined,
connectorOrApiClient: PluginLedgerConnectorBesu | BesuApi,
): Promise<{
transactions: Transaction[];
values: string[];
Expand All @@ -147,7 +145,7 @@ export class StrategyBesu implements ObtainLedgerStrategy {
topics: [[null], [Web3.utils.keccak256(key)]], //filter logs by asset key
};

const decoded = await this.getPastLogs(req, connector, api);
const decoded = await this.getPastLogs(req, connectorOrApiClient);
const transactions: Transaction[] = [];
const blocks: Map<string, EvmBlock> = new Map<string, EvmBlock>();
const values: string[] = [];
Expand All @@ -158,16 +156,14 @@ export class StrategyBesu implements ObtainLedgerStrategy {
{
transactionHash: log.transactionHash,
} as GetTransactionV1Request,
connector,
api,
connectorOrApiClient,
);

const txBlock = await this.getBlock(
{
blockHashOrBlockNumber: log.blockHash,
} as GetBlockV1Request,
connector,
api,
connectorOrApiClient,
);

this.log.debug(
Expand Down Expand Up @@ -275,107 +271,159 @@ export class StrategyBesu implements ObtainLedgerStrategy {

async getPastLogs(
req: GetPastLogsV1Request,
connector: PluginLedgerConnectorBesu | undefined,
api: BesuApi | undefined,
connectorOrApiClient: PluginLedgerConnectorBesu | BesuApi,
): Promise<EvmLog[]> {
if (connector) {
const fn = `${StrategyBesu.CLASS_NAME}#getPastLogs()`;
if (!connectorOrApiClient) {
throw new BadRequestError(`${fn} connectorOrApiClient is falsy`);
} else if (connectorOrApiClient instanceof PluginLedgerConnectorBesu) {
const connector: PluginLedgerConnectorBesu = connectorOrApiClient;
const response = await connector.getPastLogs(req);
if (response.logs) {
return response.logs;
} else {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getPastLogs: BesuAPI getPastLogs output is falsy`,
);
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
}
if (api) {
if (!response.logs) {
throw new InternalServerError(`${fn} response.logs is falsy`);
}
const { logs } = response;
if (!Array.isArray(logs)) {
throw new InternalServerError(`${fn} logs not an array`);
}
const allItemsAreEvmLog = logs.every((x) => this.isEvmLog(x));
if (!allItemsAreEvmLog) {
throw new InternalServerError(`${fn} logs has non-EvmLog items`);
}
return response.logs as EvmLog[];
} else if (connectorOrApiClient instanceof BesuApi) {
const api: BesuApi = connectorOrApiClient;
const response = await api.getPastLogsV1(req);
if (response.status < 200 || response.status >= 300) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getPastLogsV1 error with status ${response.status}: ` +
response.data,
);
}
if (!response.data.logs) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getPastLogsV1 API call successfull but output data is falsy`,
);
}
return response.data.logs as EvmLog[];
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
if (!response.status) {
throw new InternalServerError(`${fn} response.status is falsy`);
}
const { status, data, statusText, config } = response;
if (response.status < 200 || response.status > 300) {
this.log.debug("BesuAPI non-2xx HTTP response:", data, status, config);
const errorMessage = `${fn} BesuAPI error status: ${status}: ${statusText}`;
throw new InternalServerError(errorMessage);
}
if (!data) {
throw new InternalServerError(`${fn} response.data is falsy`);
}
if (!data.logs) {
throw new InternalServerError(`${fn} data.logs is falsy`);
}
const { logs } = data;
if (!Array.isArray(logs)) {
throw new InternalServerError(`${fn} logs not an array`);
}
const allItemsAreEvmLog = logs.every((x) => this.isEvmLog(x));
if (!allItemsAreEvmLog) {
throw new InternalServerError(`${fn} logs has non-EvmLog items`);
}
return response.data.logs;
}
throw new Error(
`${StrategyBesu.CLASS_NAME}#getTransaction: BesuAPI or Connector were not defined`,
throw new InternalServerError(`${fn}: neither BesuAPI nor Connector given`);
}

isEvmLog(x: any): x is EvmLog {
return (
"address" in x &&
"data" in x &&
"blockHash" in x &&
"transactionHash" in x &&
"topics" in x &&
"blockNumber" in x &&
"logIndex" in x &&
"transactionIndex" in x
);
}

async getTransaction(
req: GetTransactionV1Request,
connector: PluginLedgerConnectorBesu | undefined,
api: BesuApi | undefined,
connectorOrApiClient: PluginLedgerConnectorBesu | BesuApi,
): Promise<EvmTransaction> {
if (connector) {
const fn = `${StrategyBesu.CLASS_NAME}#getTransaction()`;
if (!connectorOrApiClient) {
} else if (connectorOrApiClient instanceof PluginLedgerConnectorBesu) {
const connector: PluginLedgerConnectorBesu = connectorOrApiClient;
const response = await connector.getTransaction(req);
if (response.transaction) {
return response.transaction;
} else {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getTransaction: BesuAPI getTransaction output is falsy`,
);
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
}
if (api) {
const txTx = await api.getTransactionV1(req);
if (!response.transaction) {
throw new InternalServerError(`${fn} response.transaction is falsy`);
}
return response.transaction;
} else if (connectorOrApiClient instanceof BesuApi) {
const api: BesuApi = connectorOrApiClient;
const response = await api.getTransactionV1(req);
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
if (!response.status) {
throw new InternalServerError(`${fn} response.status is falsy`);
}
const { status, data, statusText, config } = response;
if (response.status < 200 || response.status > 300) {
this.log.debug("BesuAPI non-2xx HTTP response:", data, status, config);

if (txTx.status < 200 || txTx.status >= 300) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getTransactionV1 error with status ${txTx.status}: ` +
txTx.data,
);
}
if (!txTx.data.transaction) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getTransactionV1 call successfull but output data is falsy`,
);
}
return txTx.data.transaction;
const errorMessage = `${fn} BesuAPI error status: ${status}: ${statusText}`;
throw new InternalServerError(errorMessage);
}
if (!data) {
throw new InternalServerError(`${fn} response.data is falsy`);
}
if (!data.transaction) {
throw new InternalServerError(`${fn} data.transaction is falsy`);
}
return response.data.transaction;
}
throw new Error(
`${StrategyBesu.CLASS_NAME}#getTransaction: BesuAPI or Connector were not defined`,
);
throw new InternalServerError(`${fn}: neither BesuAPI nor Connector given`);
}

async getBlock(
req: GetBlockV1Request,
connector: PluginLedgerConnectorBesu | undefined,
api: BesuApi | undefined,
connectorOrApiClient: PluginLedgerConnectorBesu | BesuApi,
): Promise<EvmBlock> {
if (connector) {
const fn = `${StrategyBesu.CLASS_NAME}#getBlock()`;
if (!connectorOrApiClient) {
} else if (connectorOrApiClient instanceof PluginLedgerConnectorBesu) {
const connector: PluginLedgerConnectorBesu = connectorOrApiClient;
const response = await connector.getBlock(req);
if (response.block) {
return response.block;
} else {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getBlock: BesuAPI getBlock output is falsy`,
);
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
if (!response.block) {
throw new InternalServerError(`${fn} response.block is falsy`);
}
return response.block;
} else if (connectorOrApiClient instanceof BesuApi) {
const api: BesuApi = connectorOrApiClient;
const response = await api.getBlockV1(req);
if (!response) {
throw new InternalServerError(`${fn} response is falsy`);
}
if (!response.status) {
throw new InternalServerError(`${fn} response.status is falsy`);
}
const { status, data, statusText, config } = response;
if (response.status < 200 || response.status > 300) {
this.log.debug("BesuAPI non-2xx HTTP response:", data, status, config);

const errorMessage = `${fn} BesuAPI error status: ${status}: ${statusText}`;
throw new InternalServerError(errorMessage);
}
if (!data) {
throw new InternalServerError(`${fn} response.data is falsy`);
}
if (!data.block) {
throw new InternalServerError(`${fn} data.block is falsy`);
}
return data.block;
}
if (api) {
const txBlock = await api.getBlockV1(req);
if (txBlock.status < 200 || txBlock.status >= 300) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getBlockV1 error with status ${txBlock.status}: ` +
txBlock.data,
);
}
if (!txBlock.data.block) {
throw new Error(
`${StrategyBesu.CLASS_NAME}#getAllInfoByKey: BesuAPI getBlockV1 call successfull but output data is falsy`,
);
}
return txBlock.data.block;
}
throw new Error(
`${StrategyBesu.CLASS_NAME}#getTransaction: BesuAPI or Connector were not defined`,
);
throw new InternalServerError(`${fn}: neither BesuAPI nor Connector given`);
}
}
Loading

0 comments on commit f0e959b

Please sign in to comment.