From 0d93411f1306e0150c1f05807eee776f66dc6eb4 Mon Sep 17 00:00:00 2001 From: Carsten Otto Date: Mon, 22 Nov 2021 09:31:55 +0100 Subject: [PATCH] add /api/node/PUBKEY/on-chain-costs --- .../controller/OnChainCostsControllerIT.java | 13 +++++++++++++ .../cotto/lndmanagej/controller/NodeController.java | 5 +++-- .../controller/OnChainCostsController.java | 11 +++++++++++ .../lndmanagej/controller/dto/OnChainCostsDto.java | 5 +++++ .../lndmanagej/controller/NodeControllerTest.java | 10 ++++++---- .../controller/OnChainCostsControllerTest.java | 13 +++++++++++++ 6 files changed, 51 insertions(+), 6 deletions(-) diff --git a/application/src/integrationTest/java/de/cotto/lndmanagej/controller/OnChainCostsControllerIT.java b/application/src/integrationTest/java/de/cotto/lndmanagej/controller/OnChainCostsControllerIT.java index f6b646c9..e319932d 100644 --- a/application/src/integrationTest/java/de/cotto/lndmanagej/controller/OnChainCostsControllerIT.java +++ b/application/src/integrationTest/java/de/cotto/lndmanagej/controller/OnChainCostsControllerIT.java @@ -12,14 +12,18 @@ import org.springframework.test.web.servlet.MockMvc; import java.util.Optional; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; +import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(controllers = OnChainCostsController.class) class OnChainCostsControllerIT { private static final String CHANNEL_PREFIX = "/api/channel/" + CHANNEL_ID.getShortChannelId(); + private static final String PEER_PREFIX = "/api/node/" + PUBKEY; @Autowired private MockMvc mockMvc; @@ -31,6 +35,15 @@ class OnChainCostsControllerIT { @SuppressWarnings("unused") private Metrics metrics; + @Test + void on_chain_costs_for_peer() throws Exception { + when(onChainCostService.getOpenCostsWith(PUBKEY)).thenReturn(Coins.ofSatoshis(123)); + when(onChainCostService.getCloseCostsWith(PUBKEY)).thenReturn(Coins.ofSatoshis(456)); + mockMvc.perform(get(PEER_PREFIX + "/on-chain-costs")) + .andExpect(jsonPath("$.openCosts", is("123"))) + .andExpect(jsonPath("$.closeCosts", is("456"))); + } + @Test void open_costs_for_channel() throws Exception { when(onChainCostService.getOpenCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(123))); diff --git a/application/src/main/java/de/cotto/lndmanagej/controller/NodeController.java b/application/src/main/java/de/cotto/lndmanagej/controller/NodeController.java index d613175d..64c9d66c 100644 --- a/application/src/main/java/de/cotto/lndmanagej/controller/NodeController.java +++ b/application/src/main/java/de/cotto/lndmanagej/controller/NodeController.java @@ -8,6 +8,7 @@ import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.metrics.Metrics; import de.cotto.lndmanagej.model.Channel; import de.cotto.lndmanagej.model.ChannelId; +import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.model.Node; import de.cotto.lndmanagej.model.Pubkey; import de.cotto.lndmanagej.service.ChannelService; @@ -54,8 +55,8 @@ public class NodeController { public NodeDetailsDto getDetails(@PathVariable Pubkey pubkey) { mark("getDetails"); Node node = nodeService.getNode(pubkey); - String openCosts = String.valueOf(onChainCostService.getOpenCostsWith(pubkey).satoshis()); - String closeCosts = String.valueOf(onChainCostService.getCloseCostsWith(pubkey).satoshis()); + Coins openCosts = onChainCostService.getOpenCostsWith(pubkey); + Coins closeCosts = onChainCostService.getCloseCostsWith(pubkey); return new NodeDetailsDto( pubkey, node.alias(), diff --git a/application/src/main/java/de/cotto/lndmanagej/controller/OnChainCostsController.java b/application/src/main/java/de/cotto/lndmanagej/controller/OnChainCostsController.java index 62f54b10..22f4d903 100644 --- a/application/src/main/java/de/cotto/lndmanagej/controller/OnChainCostsController.java +++ b/application/src/main/java/de/cotto/lndmanagej/controller/OnChainCostsController.java @@ -1,9 +1,11 @@ package de.cotto.lndmanagej.controller; import com.codahale.metrics.MetricRegistry; +import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.metrics.Metrics; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Coins; +import de.cotto.lndmanagej.model.Pubkey; import de.cotto.lndmanagej.service.OnChainCostService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -21,6 +23,15 @@ public class OnChainCostsController { this.metrics = metrics; } + @GetMapping("/node/{pubkey}/on-chain-costs") + public OnChainCostsDto getCostsForPeer(@PathVariable Pubkey pubkey) { + metrics.mark(MetricRegistry.name(getClass(), "getCostsForPeer")); + return new OnChainCostsDto( + onChainCostService.getOpenCostsWith(pubkey), + onChainCostService.getCloseCostsWith(pubkey) + ); + } + @GetMapping("/channel/{channelId}/open-costs") public long getOpenCostsForChannel(@PathVariable ChannelId channelId) throws CostException { metrics.mark(MetricRegistry.name(getClass(), "getOpenCostsForChannel")); diff --git a/application/src/main/java/de/cotto/lndmanagej/controller/dto/OnChainCostsDto.java b/application/src/main/java/de/cotto/lndmanagej/controller/dto/OnChainCostsDto.java index a045d7a8..98f4d553 100644 --- a/application/src/main/java/de/cotto/lndmanagej/controller/dto/OnChainCostsDto.java +++ b/application/src/main/java/de/cotto/lndmanagej/controller/dto/OnChainCostsDto.java @@ -1,4 +1,9 @@ package de.cotto.lndmanagej.controller.dto; +import de.cotto.lndmanagej.model.Coins; + public record OnChainCostsDto(String openCosts, String closeCosts) { + public OnChainCostsDto(Coins openCosts, Coins closeCosts) { + this(String.valueOf(openCosts.satoshis()), String.valueOf(closeCosts.satoshis())); + } } diff --git a/application/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java b/application/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java index 24b4917c..ec411f19 100644 --- a/application/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java +++ b/application/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java @@ -76,7 +76,7 @@ class NodeControllerTest { List.of(), List.of(), List.of(), - new OnChainCostsDto("0", "0"), + new OnChainCostsDto(Coins.NONE, Coins.NONE), true ); when(nodeService.getNode(PUBKEY_2)).thenReturn(new Node(PUBKEY_2, ALIAS_2, 0, true)); @@ -96,8 +96,10 @@ class NodeControllerTest { when(channelService.getForceClosingChannelsFor(PUBKEY_2)).thenReturn( Set.of(FORCE_CLOSING_CHANNEL, FORCE_CLOSING_CHANNEL_2, FORCE_CLOSING_CHANNEL_3) ); - when(onChainCostService.getOpenCostsWith(PUBKEY_2)).thenReturn(Coins.ofSatoshis(123)); - when(onChainCostService.getCloseCostsWith(PUBKEY_2)).thenReturn(Coins.ofSatoshis(456)); + Coins openCosts = Coins.ofSatoshis(123); + Coins closeCosts = Coins.ofSatoshis(456); + when(onChainCostService.getOpenCostsWith(PUBKEY_2)).thenReturn(openCosts); + when(onChainCostService.getCloseCostsWith(PUBKEY_2)).thenReturn(closeCosts); NodeDetailsDto expectedDetails = new NodeDetailsDto( PUBKEY_2, ALIAS_2, @@ -105,7 +107,7 @@ class NodeControllerTest { List.of(CHANNEL_ID_2, CHANNEL_ID_3), List.of(CHANNEL_ID, CHANNEL_ID_2), List.of(CHANNEL_ID, CHANNEL_ID_2, CHANNEL_ID_3), - new OnChainCostsDto("123", "456"), + new OnChainCostsDto(openCosts, closeCosts), false ); diff --git a/application/src/test/java/de/cotto/lndmanagej/controller/OnChainCostsControllerTest.java b/application/src/test/java/de/cotto/lndmanagej/controller/OnChainCostsControllerTest.java index 1fbeb9a5..624505d1 100644 --- a/application/src/test/java/de/cotto/lndmanagej/controller/OnChainCostsControllerTest.java +++ b/application/src/test/java/de/cotto/lndmanagej/controller/OnChainCostsControllerTest.java @@ -1,5 +1,6 @@ package de.cotto.lndmanagej.controller; +import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.metrics.Metrics; import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.service.OnChainCostService; @@ -12,6 +13,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.Optional; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.argThat; @@ -29,6 +31,17 @@ class OnChainCostsControllerTest { @Mock private Metrics metrics; + @Test + void getCostsForPeer() throws CostException { + Coins openCosts = Coins.ofSatoshis(123); + Coins closeCosts = Coins.ofSatoshis(456); + when(onChainCostService.getOpenCostsWith(PUBKEY)).thenReturn(openCosts); + when(onChainCostService.getCloseCostsWith(PUBKEY)).thenReturn(closeCosts); + OnChainCostsDto expected = new OnChainCostsDto(openCosts, closeCosts); + assertThat(onChainCostsController.getCostsForPeer(PUBKEY)).isEqualTo(expected); + verify(metrics).mark(argThat(name -> name.endsWith(".getCostsForPeer"))); + } + @Test void getOpenCostsForChannel() throws CostException { Coins coins = Coins.ofSatoshis(123);