Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.

Commit 688ac05

Browse files
Merge pull request #1008 from lightninglabs/show-force-close-time
Display blocks to maturity on channel detail view.
2 parents 68e979b + 71d9d55 commit 688ac05

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

src/action/channel.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* call the corresponding GRPC apis for channel management.
44
*/
55

6-
import { toSatoshis, poll } from '../helper';
6+
import { toSatoshis, poll, getTimeTilAvailable } from '../helper';
77
import * as log from './log';
88

99
class ChannelAction {
@@ -160,6 +160,7 @@ class ChannelAction {
160160
limboBalance: pfcc.limboBalance,
161161
maturityHeight: pfcc.maturityHeight,
162162
blocksTilMaturity: pfcc.blocksTilMaturity,
163+
timeTilAvailable: getTimeTilAvailable(pfcc.blocksTilMaturity),
163164
status: 'pending-force-closing',
164165
}));
165166
const wccs = response.waitingCloseChannels.map(wcc => ({

src/helper.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,23 @@ export const toLabel = (amount, settings) => {
137137
return toAmountLabel(satoshis, settings);
138138
};
139139

140+
/**
141+
* Convert a number of blocks to an amount of time in the format "X days and Y
142+
* hours" assuming 10 minutes per block.
143+
* @param {number} numBlocks The number of blocks to convert.
144+
* @return {string} The amount of time the blocks is equivalent to.
145+
*/
146+
export const getTimeTilAvailable = numBlocks => {
147+
if (!Number.isInteger(numBlocks)) {
148+
throw new Error('Invalid input!');
149+
}
150+
const days = Math.floor(numBlocks / (24 * 6));
151+
const hours = Math.floor((numBlocks % (24 * 6)) / 6);
152+
const daysString = days === 1 ? 'day' : 'days';
153+
const hoursString = hours === 1 ? 'hour' : 'hours';
154+
return `${days} ${daysString} and ${hours} ${hoursString}`;
155+
};
156+
140157
/**
141158
* Split '_' separated words and convert to uppercase
142159
* @param {string} value The input string

src/view/channel-detail.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ const ChannelDetailView = ({ store, nav }) => (
4848
<DetailField name="Status">
4949
{store.selectedChannel.statusLabel}
5050
</DetailField>
51+
{store.selectedChannel.timeTilAvailable ? (
52+
<DetailField name="Time Til Available">
53+
{store.selectedChannel.timeTilAvailable}
54+
</DetailField>
55+
) : null}
5156
<DetailField name="Capacity">
5257
{store.selectedChannel.capacityLabel} {store.unitLabel}
5358
</DetailField>

test/unit/action/channel.spec.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@ describe('Action Channels Unit Tests', () => {
146146
grpc.sendCommand.withArgs('pendingChannels').resolves({
147147
pendingOpenChannels: [{ channel: { ...pendingChannel } }],
148148
pendingClosingChannels: [{ channel: { ...pendingChannel } }],
149-
pendingForceClosingChannels: [{ channel: { ...pendingChannel } }],
149+
pendingForceClosingChannels: [
150+
{
151+
channel: { ...pendingChannel },
152+
blocksTilMaturity: 463,
153+
},
154+
],
150155
waitingCloseChannels: [{ channel: { ...pendingChannel } }],
151156
totalLimboBalance: 1,
152157
});
@@ -156,6 +161,9 @@ describe('Action Channels Unit Tests', () => {
156161
remotePubkey: 'some-key',
157162
fundingTxId: 'FFFF',
158163
});
164+
expect(store.pendingChannels[2], 'to satisfy', {
165+
timeTilAvailable: '3 days and 5 hours',
166+
});
159167
});
160168

161169
it('should log error on failure', async () => {

test/unit/helper.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,4 +817,32 @@ describe('Helpers Unit Tests', () => {
817817
);
818818
});
819819
});
820+
821+
describe('getTimeTilAvailable()', () => {
822+
it('should format blocks to human-readable time', () => {
823+
const numBlocks = 463;
824+
const time = helpers.getTimeTilAvailable(numBlocks);
825+
expect(time, 'to equal', '3 days and 5 hours');
826+
});
827+
828+
it('should error on undefined', () => {
829+
expect(
830+
helpers.getTimeTilAvailable.bind(undefined),
831+
'to throw',
832+
/Invalid/
833+
);
834+
});
835+
836+
it('should work for 1 day and 1 hour', () => {
837+
const numBlocks = 150;
838+
const time = helpers.getTimeTilAvailable(numBlocks);
839+
expect(time, 'to equal', '1 day and 1 hour');
840+
});
841+
842+
it('should work for 0', () => {
843+
const numBlocks = 0;
844+
const time = helpers.getTimeTilAvailable(numBlocks);
845+
expect(time, 'to equal', '0 days and 0 hours');
846+
});
847+
});
820848
});

0 commit comments

Comments
 (0)