From 3f5ea4ce8e49b7d7b5178881014ab39e309afa78 Mon Sep 17 00:00:00 2001 From: Carsten Otto Date: Thu, 9 Dec 2021 16:59:03 +0100 Subject: [PATCH] add rebalance costs to channel details --- .../controller/ChannelControllerIT.java | 10 ++++++++++ .../lndmanagej/controller/ChannelController.java | 14 +++++++++++++- .../controller/dto/ChannelDetailsDto.java | 5 +++++ .../controller/dto/OffChainCostsDto.java | 12 ++++++++++++ .../controller/ChannelControllerTest.java | 13 +++++++++++++ .../controller/dto/ChannelDetailsDtoTest.java | 9 +++++++++ .../controller/dto/OffChainCostsDtoTest.java | 15 +++++++++++++++ 7 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 web/src/main/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDto.java create mode 100644 web/src/test/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDtoTest.java diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java index f77c7b64..b70c81f9 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java @@ -7,6 +7,7 @@ import de.cotto.lndmanagej.service.BalanceService; import de.cotto.lndmanagej.service.ChannelService; import de.cotto.lndmanagej.service.FeeService; import de.cotto.lndmanagej.service.NodeService; +import de.cotto.lndmanagej.service.OffChainCostService; import de.cotto.lndmanagej.service.OnChainCostService; import de.cotto.lndmanagej.service.PolicyService; import org.junit.jupiter.api.Test; @@ -62,6 +63,9 @@ class ChannelControllerIT { @MockBean private OnChainCostService onChainCostService; + @MockBean + private OffChainCostService offChainCostService; + @MockBean private BalanceService balanceService; @@ -122,6 +126,8 @@ class ChannelControllerIT { when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE)); when(onChainCostService.getOpenCostsForChannelId(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(1000))); when(onChainCostService.getCloseCostsForChannelId(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(2000))); + when(offChainCostService.getRebalanceSourceCostsForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(1)); + when(offChainCostService.getRebalanceTargetCostsForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(2)); when(balanceService.getBalanceInformation(CHANNEL_ID)).thenReturn(Optional.of(BALANCE_INFORMATION_2)); when(feeService.getFeeReportForChannel(CHANNEL_ID)).thenReturn(FEE_REPORT); mockMvc.perform(get(DETAILS_PREFIX)) @@ -142,6 +148,8 @@ class ChannelControllerIT { .andExpect(jsonPath("$.status.openClosed", is("OPEN"))) .andExpect(jsonPath("$.onChainCosts.openCosts", is("1000"))) .andExpect(jsonPath("$.onChainCosts.closeCosts", is("2000"))) + .andExpect(jsonPath("$.offChainCosts.rebalanceSource", is("1"))) + .andExpect(jsonPath("$.offChainCosts.rebalanceTarget", is("2"))) .andExpect(jsonPath("$.balance.localBalance", is("2000"))) .andExpect(jsonPath("$.balance.localReserve", is("200"))) .andExpect(jsonPath("$.balance.localAvailable", is("1800"))) @@ -162,6 +170,8 @@ class ChannelControllerIT { void getChannelDetails_closed_channel() throws Exception { when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); when(feeService.getFeeReportForChannel(CHANNEL_ID)).thenReturn(new FeeReport(Coins.NONE, Coins.NONE)); + when(offChainCostService.getRebalanceSourceCostsForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(1)); + when(offChainCostService.getRebalanceTargetCostsForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(2)); mockMvc.perform(get(DETAILS_PREFIX)) .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) .andExpect(jsonPath("$.closeDetails.height", is(987_654))) diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java b/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java index c506b20d..bd7d7226 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java @@ -7,6 +7,7 @@ import de.cotto.lndmanagej.controller.dto.ChannelDto; import de.cotto.lndmanagej.controller.dto.ClosedChannelDetailsDto; import de.cotto.lndmanagej.controller.dto.FeeReportDto; import de.cotto.lndmanagej.controller.dto.ObjectMapperConfiguration; +import de.cotto.lndmanagej.controller.dto.OffChainCostsDto; import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.controller.dto.PoliciesDto; import de.cotto.lndmanagej.model.BalanceInformation; @@ -21,6 +22,7 @@ import de.cotto.lndmanagej.service.BalanceService; import de.cotto.lndmanagej.service.ChannelService; import de.cotto.lndmanagej.service.FeeService; import de.cotto.lndmanagej.service.NodeService; +import de.cotto.lndmanagej.service.OffChainCostService; import de.cotto.lndmanagej.service.OnChainCostService; import de.cotto.lndmanagej.service.PolicyService; import org.springframework.context.annotation.Import; @@ -42,6 +44,7 @@ public class ChannelController { private final OnChainCostService onChainCostService; private final PolicyService policyService; private final FeeService feeService; + private final OffChainCostService offChainCostService; public ChannelController( ChannelService channelService, @@ -49,7 +52,8 @@ public class ChannelController { BalanceService balanceService, OnChainCostService onChainCostService, PolicyService policyService, - FeeService feeService + FeeService feeService, + OffChainCostService offChainCostService ) { this.channelService = channelService; this.nodeService = nodeService; @@ -57,6 +61,7 @@ public class ChannelController { this.onChainCostService = onChainCostService; this.policyService = policyService; this.feeService = feeService; + this.offChainCostService = offChainCostService; } @Timed @@ -84,6 +89,7 @@ public class ChannelController { remoteAlias, getBalanceInformation(channelId), getOnChainCosts(channelId), + getOffChainCosts(channelId), getPoliciesForChannel(localChannel), getCloseDetailsForChannel(localChannel), getFeeReportDto(localChannel.getId()) @@ -144,6 +150,12 @@ public class ChannelController { return new OnChainCostsDto(openCosts, closeCosts); } + private OffChainCostsDto getOffChainCosts(ChannelId channelId) { + Coins rebalanceSource = offChainCostService.getRebalanceSourceCostsForChannel(channelId); + Coins rebalanceTarget = offChainCostService.getRebalanceTargetCostsForChannel(channelId); + return new OffChainCostsDto(rebalanceSource, rebalanceTarget); + } + private ClosedChannelDetailsDto getCloseDetailsForChannel(LocalChannel localChannel) { if (localChannel.isClosed()) { ClosedChannel closedChannel = localChannel.getAsClosedChannel(); diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java index 5ac348b3..9568367d 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java @@ -21,6 +21,7 @@ public record ChannelDetailsDto( ChannelStatusDto status, BalanceInformationDto balance, OnChainCostsDto onChainCosts, + OffChainCostsDto offChainCosts, PoliciesDto policies, ClosedChannelDetailsDto closeDetails, FeeReportDto feeReport @@ -30,6 +31,7 @@ public record ChannelDetailsDto( String remoteAlias, BalanceInformation balanceInformation, OnChainCostsDto onChainCosts, + OffChainCostsDto offChainCosts, PoliciesDto policies, FeeReportDto feeReport ) { @@ -48,6 +50,7 @@ public record ChannelDetailsDto( channelDto.status(), BalanceInformationDto.createFromModel(balanceInformation), onChainCosts, + offChainCosts, policies, channelDto.closeDetails(), feeReport @@ -59,6 +62,7 @@ public record ChannelDetailsDto( String remoteAlias, BalanceInformation balanceInformation, OnChainCostsDto onChainCosts, + OffChainCostsDto offChainCosts, PoliciesDto policies, ClosedChannelDetailsDto closeDetails, FeeReportDto feeReport @@ -68,6 +72,7 @@ public record ChannelDetailsDto( remoteAlias, balanceInformation, onChainCosts, + offChainCosts, policies, feeReport ); diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDto.java new file mode 100644 index 00000000..939f05c4 --- /dev/null +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDto.java @@ -0,0 +1,12 @@ +package de.cotto.lndmanagej.controller.dto; + +import de.cotto.lndmanagej.model.Coins; + +public record OffChainCostsDto(String rebalanceSource, String rebalanceTarget) { + public OffChainCostsDto(Coins rebalanceSource, Coins rebalanceTarget) { + this( + String.valueOf(rebalanceSource.milliSatoshis()), + String.valueOf(rebalanceTarget.milliSatoshis()) + ); + } +} diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java index 4d0146dd..65a5d417 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java @@ -5,6 +5,7 @@ import de.cotto.lndmanagej.controller.dto.ChannelDetailsDto; import de.cotto.lndmanagej.controller.dto.ChannelDto; import de.cotto.lndmanagej.controller.dto.ClosedChannelDetailsDto; import de.cotto.lndmanagej.controller.dto.FeeReportDto; +import de.cotto.lndmanagej.controller.dto.OffChainCostsDto; import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.controller.dto.PoliciesDto; import de.cotto.lndmanagej.model.BalanceInformation; @@ -16,6 +17,7 @@ import de.cotto.lndmanagej.service.BalanceService; import de.cotto.lndmanagej.service.ChannelService; import de.cotto.lndmanagej.service.FeeService; import de.cotto.lndmanagej.service.NodeService; +import de.cotto.lndmanagej.service.OffChainCostService; import de.cotto.lndmanagej.service.OnChainCostService; import de.cotto.lndmanagej.service.PolicyService; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +47,10 @@ import static org.mockito.Mockito.when; class ChannelControllerTest { private static final Coins OPEN_COSTS = Coins.ofSatoshis(1); private static final Coins CLOSE_COSTS = Coins.ofSatoshis(2); + private static final Coins SOURCE_COSTS = Coins.ofSatoshis(3); + private static final Coins TARGET_COSTS = Coins.ofSatoshis(4); private static final OnChainCostsDto ON_CHAIN_COSTS = new OnChainCostsDto(OPEN_COSTS, CLOSE_COSTS); + private static final OffChainCostsDto OFF_CHAIN_COSTS = new OffChainCostsDto(SOURCE_COSTS, TARGET_COSTS); private static final PoliciesDto FEE_CONFIGURATION_DTO = PoliciesDto.createFromModel(POLICIES); private static final ClosedChannelDetailsDto CLOSED_CHANNEL_DETAILS_DTO = new ClosedChannelDetailsDto(CloseInitiator.REMOTE, 987_654); @@ -67,6 +72,9 @@ class ChannelControllerTest { @Mock private OnChainCostService onChainCostService; + @Mock + private OffChainCostService offChainCostService; + @Mock private PolicyService policyService; @@ -77,6 +85,8 @@ class ChannelControllerTest { void setUp() { lenient().when(onChainCostService.getOpenCostsForChannelId(CHANNEL_ID)).thenReturn(Optional.of(OPEN_COSTS)); lenient().when(onChainCostService.getCloseCostsForChannelId(CHANNEL_ID)).thenReturn(Optional.of(CLOSE_COSTS)); + lenient().when(offChainCostService.getRebalanceSourceCostsForChannel(CHANNEL_ID)).thenReturn(SOURCE_COSTS); + lenient().when(offChainCostService.getRebalanceTargetCostsForChannel(CHANNEL_ID)).thenReturn(TARGET_COSTS); lenient().when(policyService.getPolicies(CHANNEL_ID)).thenReturn(POLICIES); lenient().when(feeService.getFeeReportForChannel(CHANNEL_ID)).thenReturn(FEE_REPORT); } @@ -114,6 +124,7 @@ class ChannelControllerTest { ALIAS_2, LOCAL_OPEN_CHANNEL.getBalanceInformation(), ON_CHAIN_COSTS, + OFF_CHAIN_COSTS, FEE_CONFIGURATION_DTO, ClosedChannelDetailsDto.UNKNOWN, FEE_REPORT_DTO @@ -133,6 +144,7 @@ class ChannelControllerTest { ALIAS_2, LOCAL_OPEN_CHANNEL_PRIVATE.getBalanceInformation(), ON_CHAIN_COSTS, + OFF_CHAIN_COSTS, FEE_CONFIGURATION_DTO, ClosedChannelDetailsDto.UNKNOWN, FEE_REPORT_DTO @@ -218,6 +230,7 @@ class ChannelControllerTest { ALIAS_2, BalanceInformation.EMPTY, ON_CHAIN_COSTS, + OFF_CHAIN_COSTS, PoliciesDto.EMPTY, new ClosedChannelDetailsDto(closeInitiator, closeHeight), FEE_REPORT_DTO diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java index 14b6c8cc..252c6513 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java @@ -19,6 +19,8 @@ import static org.assertj.core.api.Assertions.assertThat; class ChannelDetailsDtoTest { private static final OnChainCostsDto ON_CHAIN_COSTS = new OnChainCostsDto(Coins.ofSatoshis(1), Coins.ofSatoshis(2)); + private static final OffChainCostsDto OFF_CHAIN_COSTS = + new OffChainCostsDto(Coins.ofSatoshis(3), Coins.ofSatoshis(4)); private static final ClosedChannelDetailsDto CLOSE_DETAILS = new ClosedChannelDetailsDto("abc", 123); private static final FeeReportDto FEE_REPORT = new FeeReportDto(Coins.ofMilliSatoshis(1234), Coins.ofMilliSatoshis(567)); @@ -27,6 +29,7 @@ class ChannelDetailsDtoTest { ALIAS, BALANCE_INFORMATION, ON_CHAIN_COSTS, + OFF_CHAIN_COSTS, PoliciesDto.EMPTY, CLOSE_DETAILS, FEE_REPORT @@ -84,6 +87,7 @@ class ChannelDetailsDtoTest { ALIAS, BALANCE_INFORMATION, ON_CHAIN_COSTS, + OFF_CHAIN_COSTS, PoliciesDto.EMPTY, CLOSE_DETAILS, FEE_REPORT @@ -112,4 +116,9 @@ class ChannelDetailsDtoTest { void onChainCosts() { assertThat(CHANNEL_DETAILS_DTO.onChainCosts()).isEqualTo(ON_CHAIN_COSTS); } + + @Test + void offChainCosts() { + assertThat(CHANNEL_DETAILS_DTO.offChainCosts()).isEqualTo(OFF_CHAIN_COSTS); + } } \ No newline at end of file diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDtoTest.java new file mode 100644 index 00000000..dca95f6b --- /dev/null +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/OffChainCostsDtoTest.java @@ -0,0 +1,15 @@ +package de.cotto.lndmanagej.controller.dto; + +import de.cotto.lndmanagej.model.Coins; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class OffChainCostsDtoTest { + @Test + void converts_to_msat_strings() { + OffChainCostsDto dto = new OffChainCostsDto(Coins.ofMilliSatoshis(1), Coins.ofMilliSatoshis(1_234)); + assertThat(dto.rebalanceSource()).isEqualTo("1"); + assertThat(dto.rebalanceTarget()).isEqualTo("1234"); + } +} \ No newline at end of file