From a5025d0b5b96834ed5107041295e1f9d226cdf3f Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 13 Feb 2024 14:52:08 +0000 Subject: [PATCH 1/4] Improve log messages --- src/server.tsx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/server.tsx b/src/server.tsx index e5963be..fb22ae3 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -150,11 +150,11 @@ async function fetchMempoolFees() : Promise { MEMPOOL_FEES_URL && fetchAndHandle(MEMPOOL_FEES_URL, 'json'), MEMPOOL_FEES_URL_FALLBACK && fetchAndHandle(MEMPOOL_FEES_URL_FALLBACK, 'json'), ].filter(Boolean); - const res = await Promise.allSettled(tasks); - console.debug('Fetched mempool fees', res); + const data = await Promise.allSettled(tasks); + console.debug({ message: 'Fetched data from mempool: {data}', data }); - let res0 = getValueFromFulfilledPromise(res[0]); - let res1 = getValueFromFulfilledPromise(res[1]); + let res0 = getValueFromFulfilledPromise(data[0]); + let res1 = getValueFromFulfilledPromise(data[1]); // If all of the response properties are 1, then the response is an error (probably the mempool data is not available). const isRes0Invalid = !res0 || (Object.values(res0).every((value) => value === 1)); @@ -175,11 +175,11 @@ async function fetchEsploraFees() : Promise { ESPLORA_FEE_ESTIMATES_URL && fetchAndHandle(ESPLORA_FEE_ESTIMATES_URL, 'json'), ESPLORA_FEE_ESTIMATES_URL_FALLBACK && fetchAndHandle(ESPLORA_FEE_ESTIMATES_URL_FALLBACK, 'json'), ].filter(Boolean); - const res = await Promise.allSettled(tasks); - console.debug('Fetched esplora fees', res); + const data = await Promise.allSettled(tasks); + console.debug({ message: 'Fetched data from esplora: {data}', data }); - let res0 = getValueFromFulfilledPromise(res[0]); - let res1 = getValueFromFulfilledPromise(res[1]); + let res0 = getValueFromFulfilledPromise(data[0]); + let res1 = getValueFromFulfilledPromise(data[1]); return res0 || res1 || null; } @@ -193,7 +193,7 @@ async function fetchBitcoindFees() : Promise { } return new Promise((resolve, _) => { - var result : FeeByBlockTarget = {}; + var data : FeeByBlockTarget = {}; // Define the targets for which to fetch fee estimates. const targets = BITCOIND_CONF_TARGETS; @@ -230,13 +230,13 @@ async function fetchBitcoindFees() : Promise { if (feeRate) { // convert the returned value to satoshis, as it's currently returned in BTC. const satPerKB : number = feeRate * 1e8; - result[target] = applyFeeMultiplier(satPerKB); + data[target] = applyFeeMultiplier(satPerKB); } else { console.error(`Failed to fetch fee estimate from bitcoind for confirmation target ${target}`, response[i].result?.errors); } }); - console.debug('Fetched bitcoind fees', result); - resolve(result); + console.debug({ message: 'Fetched data from bitcoind: {data}', data }); + resolve(data); } }); }); @@ -277,7 +277,7 @@ async function getEstimates() : Promise { let estimates: Estimates | undefined = cache.get(CACHE_KEY); if (estimates) { - console.info('Got estimates (from cache)', estimates); + console.info({ message: 'Got estimates from cache: ${estimates}', estimates }); return estimates; } @@ -300,7 +300,7 @@ async function getEstimates() : Promise { cache.set(CACHE_KEY, estimates); - console.info('Got estimates', estimates); + console.info({ message: 'Got estimates: {estimates}', estimates }); return estimates; } From 1fbb5e9a7f9bc5c2105b174ba0dc6b1b78cd3787 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 13 Feb 2024 14:52:35 +0000 Subject: [PATCH 2/4] Add -it switches for docker exec --- test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/README.md b/test/README.md index 1c4b993..c6b2dbc 100644 --- a/test/README.md +++ b/test/README.md @@ -9,7 +9,7 @@ cd test/fixtures && docker-compose up To fill the mempool, exec onto the container and run the `init.sh` script: ```bash -docker exec bitcoin-blended-fee-estimator-bitcoind-1 bash +docker exec -it bitcoin-blended-fee-estimator-bitcoind-1 bash /init.sh ``` From c27ffe580eb97dcd52a5895fbb76d31e99265c0d Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 13 Feb 2024 14:57:50 +0000 Subject: [PATCH 3/4] Skip result processing if nothing to process --- src/server.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/server.tsx b/src/server.tsx index fb22ae3..b6d3c7e 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -150,6 +150,10 @@ async function fetchMempoolFees() : Promise { MEMPOOL_FEES_URL && fetchAndHandle(MEMPOOL_FEES_URL, 'json'), MEMPOOL_FEES_URL_FALLBACK && fetchAndHandle(MEMPOOL_FEES_URL_FALLBACK, 'json'), ].filter(Boolean); + if (tasks.length === 0) { + return null; + } + const data = await Promise.allSettled(tasks); console.debug({ message: 'Fetched data from mempool: {data}', data }); @@ -175,6 +179,10 @@ async function fetchEsploraFees() : Promise { ESPLORA_FEE_ESTIMATES_URL && fetchAndHandle(ESPLORA_FEE_ESTIMATES_URL, 'json'), ESPLORA_FEE_ESTIMATES_URL_FALLBACK && fetchAndHandle(ESPLORA_FEE_ESTIMATES_URL_FALLBACK, 'json'), ].filter(Boolean); + if (tasks.length === 0) { + return null; + } + const data = await Promise.allSettled(tasks); console.debug({ message: 'Fetched data from esplora: {data}', data }); From dbd4f1e69b2c60499d74797bcd13589a480915c3 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 13 Feb 2024 15:04:48 +0000 Subject: [PATCH 4/4] Improve log formatting --- src/server.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/server.tsx b/src/server.tsx index b6d3c7e..578f235 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -84,7 +84,7 @@ function getValueFromFulfilledPromise(result: PromiseSettledResult) { // NOTE: fetch signal abortcontroller does not work on Bun. // See https://github.com/oven-sh/bun/issues/2489 async function fetchWithTimeout(url: string, timeout: number = TIMEOUT): Promise { - console.debug(`Starting fetch request to ${url}`); + console.debug({ message: `Starting fetch request to ${url}` }); const fetchPromise = fetch(url); const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Request timed out after ${timeout} ms`)), timeout) @@ -101,7 +101,7 @@ async function fetchAndProcess(url: string, expectedResponseType: ExpectedRespon if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - console.debug(`Successfully fetched data from ${url}`); + console.debug({message: `Successfully fetched data from ${url}` }); const contentType = response.headers.get("content-type"); if (expectedResponseType === 'json' && contentType?.includes("application/json")) { @@ -134,7 +134,7 @@ async function fetchAndHandle(url: string, expectedResponseType: ExpectedRespons return result; } catch (error) { if (fallbackUrl) { - console.debug('Trying fallback URL', fallbackUrl); + console.debug({ message: 'Trying fallback URL: ${fallbackUrl}' }); return fetchAndProcess(fallbackUrl, expectedResponseType); } else { throw new Error(`Fetch request to ${url} failed and no fallback URL was provided.`); @@ -228,9 +228,9 @@ async function fetchBitcoindFees() : Promise { }); } - rpc.batch(batchCall, (err: Error | null, response: BitcoindRpcBatchResponse[]) => { - if (err) { - console.error('Unable to fetch fee estimates from bitcoind', err); + rpc.batch(batchCall, (error: Error | null, response: BitcoindRpcBatchResponse[]) => { + if (error) { + console.error({ message: 'Unable to fetch fee estimates from bitcoind: {error}', error }); resolve(null); } else { targets.forEach((target, i) => { @@ -240,7 +240,8 @@ async function fetchBitcoindFees() : Promise { const satPerKB : number = feeRate * 1e8; data[target] = applyFeeMultiplier(satPerKB); } else { - console.error(`Failed to fetch fee estimate from bitcoind for confirmation target ${target}`, response[i].result?.errors); + console.error({ message: `Failed to fetch fee estimate from bitcoind for confirmation target ${target}: {errors}`, + errors: response[i].result?.errors}); } }); console.debug({ message: 'Fetched data from bitcoind: {data}', data }); @@ -402,7 +403,7 @@ function calculateFees(mempoolFeeEstimates: MempoolFeeEstimates, esploraFeeEstim // Get the minimum fee. If the mempool fee estimates are not available, use a default value of FEE_MINIMUM sat/vbyte as a safety net. const minFee = (mempoolFeeEstimates?.minimumFee ?? FEE_MINIMUM) * 1000; - console.debug('Using minimum fee:', minFee); + console.debug({ message: 'Using minimum fee: {minFee}', minFee }); // Return fees filterd to remove any that are lower than the determined minimum fee. if (minFee) { @@ -546,6 +547,6 @@ export default { } process.on('SIGINT', function() { - console.info("Caught interrupt signal. Exiting."); + console.info({ message: "Caught interrupt signal. Exiting." }); process.exit(); });