diff --git a/backend/src/main/java/de/cotto/lndmanagej/service/FeeService.java b/backend/src/main/java/de/cotto/lndmanagej/service/FeeService.java index 234bbf7b..5e6f6dad 100644 --- a/backend/src/main/java/de/cotto/lndmanagej/service/FeeService.java +++ b/backend/src/main/java/de/cotto/lndmanagej/service/FeeService.java @@ -6,6 +6,7 @@ import de.cotto.lndmanagej.caching.CacheBuilder; import de.cotto.lndmanagej.forwardinghistory.ForwardingEventsDao; import de.cotto.lndmanagej.model.Channel; import de.cotto.lndmanagej.model.ChannelId; +import de.cotto.lndmanagej.model.ClosedChannel; import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.model.FeeReport; import de.cotto.lndmanagej.model.ForwardingEvent; @@ -13,19 +14,24 @@ import de.cotto.lndmanagej.model.Pubkey; import org.springframework.stereotype.Component; import java.time.Duration; -import java.time.Period; @Component public class FeeService { - private static final Period DEFAULT_MAX_AGE = Period.ofYears(Integer.MAX_VALUE); + private static final Duration DEFAULT_MAX_AGE = Duration.ofDays(365 * 1_000); private final ForwardingEventsDao forwardingEventsDao; private final ChannelService channelService; + private final OwnNodeService ownNodeService; private final LoadingCache cacheForOpenChannels; private final LoadingCache cacheForClosedChannels; - public FeeService(ForwardingEventsDao forwardingEventsDao, ChannelService channelService) { + public FeeService( + ForwardingEventsDao forwardingEventsDao, + ChannelService channelService, + OwnNodeService ownNodeService + ) { this.forwardingEventsDao = forwardingEventsDao; this.channelService = channelService; + this.ownNodeService = ownNodeService; cacheForOpenChannels = new CacheBuilder() .withRefresh(Duration.ofSeconds(5)) .withExpiry(Duration.ofSeconds(10)) @@ -41,7 +47,7 @@ public class FeeService { } @Timed - public FeeReport getFeeReportForPeer(Pubkey pubkey, Period maxAge) { + public FeeReport getFeeReportForPeer(Pubkey pubkey, Duration maxAge) { return channelService.getAllChannelsWith(pubkey).parallelStream() .map(Channel::getId) .map(channelId -> getFeeReportForChannel(channelId, maxAge)) @@ -53,12 +59,16 @@ public class FeeService { } @Timed - public FeeReport getFeeReportForChannel(ChannelId channelId, Period maxAge) { + public FeeReport getFeeReportForChannel(ChannelId channelId, Duration maxAge) { CacheKey cacheKey = new CacheKey(channelId, maxAge); - if (channelService.isClosed(channelId)) { - return cacheForClosedChannels.get(cacheKey); + ClosedChannel closedChannel = channelService.getClosedChannel(channelId).orElse(null); + if (closedChannel == null) { + return cacheForOpenChannels.get(cacheKey); } - return cacheForOpenChannels.get(cacheKey); + if (isClosedLongerThan(closedChannel, maxAge)) { + return FeeReport.EMPTY; + } + return cacheForClosedChannels.get(cacheKey); } private FeeReport getFeeReportForChannelWithoutCache(CacheKey cacheKey) { @@ -68,19 +78,25 @@ public class FeeService { ); } - private Coins getEarnedFeesForChannel(ChannelId channelId, Period maxAge) { + private Coins getEarnedFeesForChannel(ChannelId channelId, Duration maxAge) { return forwardingEventsDao.getEventsWithOutgoingChannel(channelId, maxAge).parallelStream() .map(ForwardingEvent::fees) .reduce(Coins.NONE, Coins::add); } - private Coins getSourcedFeesForChannel(ChannelId channelId, Period maxAge) { + private Coins getSourcedFeesForChannel(ChannelId channelId, Duration maxAge) { return forwardingEventsDao.getEventsWithIncomingChannel(channelId, maxAge).parallelStream() .map(ForwardingEvent::fees) .reduce(Coins.NONE, Coins::add); } + private boolean isClosedLongerThan(ClosedChannel closedChannel, Duration maxAge) { + int blocksSinceClose = ownNodeService.getBlockHeight() - closedChannel.getCloseHeight(); + int daysClosedWithSafetyMargin = (int) (0.5 * blocksSinceClose * 10.0 / 60 / 24); + return maxAge.minus(Duration.ofDays(daysClosedWithSafetyMargin)).isNegative(); + } + @SuppressWarnings("UnusedVariable") - private record CacheKey(ChannelId channelId, Period maxAge) { + private record CacheKey(ChannelId channelId, Duration maxAge) { } } diff --git a/backend/src/test/java/de/cotto/lndmanagej/service/FeeServiceTest.java b/backend/src/test/java/de/cotto/lndmanagej/service/FeeServiceTest.java index 442d6124..81a10e5d 100644 --- a/backend/src/test/java/de/cotto/lndmanagej/service/FeeServiceTest.java +++ b/backend/src/test/java/de/cotto/lndmanagej/service/FeeServiceTest.java @@ -3,14 +3,16 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.forwardinghistory.ForwardingEventsDao; import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.model.FeeReport; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.time.Period; +import java.time.Duration; import java.util.List; +import java.util.Optional; import java.util.Set; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; @@ -23,13 +25,17 @@ import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHAN import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; import static de.cotto.lndmanagej.model.WaitingCloseChannelFixtures.WAITING_CLOSE_CHANNEL_2; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class FeeServiceTest { - private static final Period DEFAULT_MAX_DURATION = Period.ofYears(Integer.MAX_VALUE); + private static final Duration DEFAULT_MAX_DURATION = Duration.ofDays(365 * 1_000); + private static final int BLOCK_HEIGHT = 700_000; @InjectMocks private FeeService feeService; @@ -40,6 +46,14 @@ class FeeServiceTest { @Mock private ChannelService channelService; + @Mock + private OwnNodeService ownNodeService; + + @BeforeEach + void setUp() { + lenient().when(ownNodeService.getBlockHeight()).thenReturn(BLOCK_HEIGHT); + } + @Test void getFeeReportForChannel() { when(dao.getEventsWithOutgoingChannel(CHANNEL_ID, DEFAULT_MAX_DURATION)) @@ -60,7 +74,7 @@ class FeeServiceTest { @Test void getFeeReportForChannel_with_day_limit() { - Period maxAge = Period.ofDays(7); + Duration maxAge = Duration.ofDays(7); assertThat(feeService.getFeeReportForChannel(CHANNEL_ID, maxAge)) .isEqualTo(new FeeReport(Coins.NONE, Coins.NONE)); verify(dao).getEventsWithIncomingChannel(CHANNEL_ID, maxAge); @@ -76,7 +90,7 @@ class FeeServiceTest { @Test void getFeeReportForChannel_closed() { - when(channelService.isClosed(CHANNEL_ID)).thenReturn(true); + when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); when(dao.getEventsWithOutgoingChannel(CHANNEL_ID, DEFAULT_MAX_DURATION)) .thenReturn(List.of(FORWARDING_EVENT)); assertThat(feeService.getFeeReportForChannel(CHANNEL_ID)) @@ -85,12 +99,32 @@ class FeeServiceTest { @Test void getFeeReportForChannel_closed_cached() { - when(channelService.isClosed(CHANNEL_ID)).thenReturn(true); + when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); feeService.getFeeReportForChannel(CHANNEL_ID); feeService.getFeeReportForChannel(CHANNEL_ID); verify(dao, times(1)).getEventsWithIncomingChannel(CHANNEL_ID, DEFAULT_MAX_DURATION); } + @Test + void getFeeReportForChannel_closed_with_max_age_just_after_channel_close_height() { + int blocks = BLOCK_HEIGHT - CLOSED_CHANNEL.getCloseHeight(); + double daysWithTenMinutesPerBlock = blocks * 10.0 / 60 / 24; + Duration duration = Duration.ofDays((int) (daysWithTenMinutesPerBlock * 0.9)); + when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); + assertThat(feeService.getFeeReportForChannel(CHANNEL_ID, duration)).isEqualTo(FeeReport.EMPTY); + verify(dao).getEventsWithIncomingChannel(any(), any()); + } + + @Test + void getFeeReportForChannel_closed_with_max_age_long_after_channel_close_height() { + int blocks = BLOCK_HEIGHT - CLOSED_CHANNEL.getCloseHeight(); + double daysWithTenMinutesPerBlock = blocks * 10.0 / 60 / 24; + Duration duration = Duration.ofDays((int) (daysWithTenMinutesPerBlock * 0.49)); + when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); + assertThat(feeService.getFeeReportForChannel(CHANNEL_ID, duration)).isEqualTo(FeeReport.EMPTY); + verify(dao, never()).getEventsWithIncomingChannel(any(), any()); + } + @Test void getFeeReportForChannel_no_forward() { when(dao.getEventsWithOutgoingChannel(CHANNEL_ID, DEFAULT_MAX_DURATION)).thenReturn(List.of()); diff --git a/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/ForwardingEventsDao.java b/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/ForwardingEventsDao.java index 8199c0b1..26dc17f2 100644 --- a/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/ForwardingEventsDao.java +++ b/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/ForwardingEventsDao.java @@ -3,7 +3,8 @@ package de.cotto.lndmanagej.forwardinghistory; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.ForwardingEvent; -import java.time.Period; +import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.Collection; import java.util.List; @@ -12,7 +13,7 @@ public interface ForwardingEventsDao { int getOffset(); - List getEventsWithOutgoingChannel(ChannelId channelId, Period maxAge); + List getEventsWithOutgoingChannel(ChannelId channelId, Duration maxAge); - List getEventsWithIncomingChannel(ChannelId channelId, Period maxAge); + List getEventsWithIncomingChannel(ChannelId channelId, Duration maxAge); } diff --git a/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImpl.java b/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImpl.java index b4f209aa..cf5fe93c 100644 --- a/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImpl.java +++ b/forwarding-history/src/main/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImpl.java @@ -6,6 +6,7 @@ import de.cotto.lndmanagej.model.ForwardingEvent; import org.springframework.stereotype.Component; import javax.transaction.Transactional; +import java.time.Duration; import java.time.Instant; import java.time.Period; import java.time.temporal.ChronoUnit; @@ -15,7 +16,6 @@ import java.util.List; @Component @Transactional public class ForwardingEventsDaoImpl implements ForwardingEventsDao { - private static final int MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1_000; private final ForwardingEventsRepository repository; public ForwardingEventsDaoImpl(ForwardingEventsRepository repository) { @@ -36,7 +36,7 @@ public class ForwardingEventsDaoImpl implements ForwardingEventsDao { } @Override - public List getEventsWithOutgoingChannel(ChannelId channelId, Period maxAge) { + public List getEventsWithOutgoingChannel(ChannelId channelId, Duration maxAge) { return repository.findByChannelOutgoingAndTimestampGreaterThan( channelId.getShortChannelId(), getAfterEpochMilliSeconds(maxAge) @@ -46,7 +46,7 @@ public class ForwardingEventsDaoImpl implements ForwardingEventsDao { } @Override - public List getEventsWithIncomingChannel(ChannelId channelId, Period maxAge) { + public List getEventsWithIncomingChannel(ChannelId channelId, Duration maxAge) { return repository.findByChannelIncomingAndTimestampGreaterThan( channelId.getShortChannelId(), getAfterEpochMilliSeconds(maxAge) @@ -55,7 +55,7 @@ public class ForwardingEventsDaoImpl implements ForwardingEventsDao { .toList(); } - private long getAfterEpochMilliSeconds(Period maxAge) { - return Instant.now().toEpochMilli() - maxAge.get(ChronoUnit.DAYS) * MILLISECONDS_PER_DAY; + private long getAfterEpochMilliSeconds(Duration maxAge) { + return Instant.now().toEpochMilli() - maxAge.getSeconds() * 1_000; } } diff --git a/forwarding-history/src/test/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImplTest.java b/forwarding-history/src/test/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImplTest.java index 2a585436..50ede3f5 100644 --- a/forwarding-history/src/test/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImplTest.java +++ b/forwarding-history/src/test/java/de/cotto/lndmanagej/forwardinghistory/persistence/ForwardingEventsDaoImplTest.java @@ -8,8 +8,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.time.Duration; import java.time.Instant; -import java.time.Period; import java.util.List; import java.util.Optional; import java.util.Set; @@ -29,7 +29,7 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class ForwardingEventsDaoImplTest { - private static final Period MAX_AGE = Period.ofYears(Integer.MAX_VALUE); + private static final Duration MAX_AGE = Duration.ofDays(365 * 1_000); @InjectMocks private ForwardingEventsDaoImpl dao; @@ -81,7 +81,7 @@ class ForwardingEventsDaoImplTest { @Test void getEventsWithOutgoingChannel_uses_max_age() { - Period maxAge = Period.ofDays(10); + Duration maxAge = Duration.ofDays(10); long timestampAfter = Instant.now().minus(maxAge).getEpochSecond() * 1_000; when(repository.findByChannelOutgoingAndTimestampGreaterThan(eq(CHANNEL_ID_2.getShortChannelId()), anyLong())) .thenReturn(List.of(ForwardingEventJpaDto.createFromModel(FORWARDING_EVENT_2))); @@ -111,7 +111,7 @@ class ForwardingEventsDaoImplTest { @Test void getEventsWithIncomingChannel_uses_max_age() { - Period maxAge = Period.ofDays(10); + Duration maxAge = Duration.ofDays(10); long timestampAfter = Instant.now().minus(maxAge).getEpochSecond() * 1_000; when(repository.findByChannelIncomingAndTimestampGreaterThan(eq(CHANNEL_ID_2.getShortChannelId()), anyLong())) .thenReturn(List.of(ForwardingEventJpaDto.createFromModel(FORWARDING_EVENT))); diff --git a/model/src/test/java/de/cotto/lndmanagej/model/BreachForceClosedChannelTest.java b/model/src/test/java/de/cotto/lndmanagej/model/BreachForceClosedChannelTest.java index dc445de9..5c15509c 100644 --- a/model/src/test/java/de/cotto/lndmanagej/model/BreachForceClosedChannelTest.java +++ b/model/src/test/java/de/cotto/lndmanagej/model/BreachForceClosedChannelTest.java @@ -76,7 +76,7 @@ class BreachForceClosedChannelTest { @Test void getCloseHeight() { - assertThat(FORCE_CLOSED_CHANNEL_BREACH.getCloseHeight()).isEqualTo(987_654); + assertThat(FORCE_CLOSED_CHANNEL_BREACH.getCloseHeight()).isEqualTo(600_000); } @Test diff --git a/model/src/test/java/de/cotto/lndmanagej/model/CoopClosedChannelTest.java b/model/src/test/java/de/cotto/lndmanagej/model/CoopClosedChannelTest.java index efec7d68..cec1f475 100644 --- a/model/src/test/java/de/cotto/lndmanagej/model/CoopClosedChannelTest.java +++ b/model/src/test/java/de/cotto/lndmanagej/model/CoopClosedChannelTest.java @@ -102,7 +102,7 @@ class CoopClosedChannelTest { @Test void getCloseHeight() { - assertThat(CLOSED_CHANNEL.getCloseHeight()).isEqualTo(987_654); + assertThat(CLOSED_CHANNEL.getCloseHeight()).isEqualTo(600_000); } @Test diff --git a/model/src/test/java/de/cotto/lndmanagej/model/ForceClosedChannelTest.java b/model/src/test/java/de/cotto/lndmanagej/model/ForceClosedChannelTest.java index e8ab80fd..ead750db 100644 --- a/model/src/test/java/de/cotto/lndmanagej/model/ForceClosedChannelTest.java +++ b/model/src/test/java/de/cotto/lndmanagej/model/ForceClosedChannelTest.java @@ -89,7 +89,7 @@ class ForceClosedChannelTest { @Test void getCloseHeight() { - assertThat(FORCE_CLOSED_CHANNEL_REMOTE.getCloseHeight()).isEqualTo(987_654); + assertThat(FORCE_CLOSED_CHANNEL_REMOTE.getCloseHeight()).isEqualTo(600_000); } @Test diff --git a/model/src/testFixtures/java/de/cotto/lndmanagej/model/ClosedChannelFixtures.java b/model/src/testFixtures/java/de/cotto/lndmanagej/model/ClosedChannelFixtures.java index 57ed0ece..5c409cd3 100644 --- a/model/src/testFixtures/java/de/cotto/lndmanagej/model/ClosedChannelFixtures.java +++ b/model/src/testFixtures/java/de/cotto/lndmanagej/model/ClosedChannelFixtures.java @@ -8,7 +8,7 @@ import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; public final class ClosedChannelFixtures { - public static final int CLOSE_HEIGHT = 987_654; + public static final int CLOSE_HEIGHT = 600_000; private ClosedChannelFixtures() { // do not instantiate 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 9c2a5e45..404bce18 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java @@ -109,7 +109,7 @@ class ChannelControllerIT { .andExpect(jsonPath("$.totalSent", is("0"))) .andExpect(jsonPath("$.totalReceived", is("0"))) .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.closeDetails.height", is(987_654))) + .andExpect(jsonPath("$.closeDetails.height", is(600_000))) .andExpect(jsonPath("$.status.active", is(false))) .andExpect(jsonPath("$.status.closed", is(true))) .andExpect(jsonPath("$.status.openClosed", is("CLOSED"))); @@ -171,7 +171,7 @@ class ChannelControllerIT { when(channelDetailsService.getDetails(CLOSED_CHANNEL)).thenReturn(CHANNEL_DETAILS_CLOSED); mockMvc.perform(get(DETAILS_PREFIX)) .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.closeDetails.height", is(987_654))) + .andExpect(jsonPath("$.closeDetails.height", is(600_000))) .andExpect(jsonPath("$.status.openClosed", is("CLOSED"))) .andExpect(jsonPath("$.totalSent", is("0"))) .andExpect(jsonPath("$.totalReceived", is("0"))) @@ -224,7 +224,7 @@ class ChannelControllerIT { when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); mockMvc.perform(get(CHANNEL_PREFIX + "/close-details")) .andExpect(jsonPath("$.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.height", is(987_654))) + .andExpect(jsonPath("$.height", is(600_000))) .andExpect(jsonPath("$.force", is(false))) .andExpect(jsonPath("$.breach", is(false))); } @@ -234,7 +234,7 @@ class ChannelControllerIT { when(channelService.getClosedChannel(CHANNEL_ID)).thenReturn(Optional.of(FORCE_CLOSED_CHANNEL)); mockMvc.perform(get(CHANNEL_PREFIX + "/close-details")) .andExpect(jsonPath("$.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.height", is(987_654))) + .andExpect(jsonPath("$.height", is(600_000))) .andExpect(jsonPath("$.force", is(true))) .andExpect(jsonPath("$.breach", is(false))); } @@ -245,7 +245,7 @@ class ChannelControllerIT { mockMvc.perform(get(CHANNEL_PREFIX + "/close-details")) .andExpect(jsonPath("$.breach", is(true))) .andExpect(jsonPath("$.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.height", is(987_654))) + .andExpect(jsonPath("$.height", is(600_000))) .andExpect(jsonPath("$.force", is(true))); } diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java index e32a2f0e..29fc73e3 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java @@ -14,7 +14,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; -import java.time.Period; +import java.time.Duration; import java.util.List; import java.util.Set; @@ -149,7 +149,7 @@ class NodeControllerIT { @Test void getFeeReport_last_days() throws Exception { - when(feeService.getFeeReportForPeer(PUBKEY, Period.ofDays(123))).thenReturn(FEE_REPORT); + when(feeService.getFeeReportForPeer(PUBKEY, Duration.ofDays(123))).thenReturn(FEE_REPORT); mockMvc.perform(get(NODE_PREFIX + "/fee-report/last-days/123")) .andExpect(jsonPath("$.earned", is("1234"))) .andExpect(jsonPath("$.sourced", is("567"))); diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/NodeController.java b/web/src/main/java/de/cotto/lndmanagej/controller/NodeController.java index 3c0e602a..ff4ff305 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/NodeController.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/NodeController.java @@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.time.Duration; import java.time.Period; import java.util.List; import java.util.Set; @@ -91,7 +92,7 @@ public class NodeController { @Timed @GetMapping("/fee-report/last-days/{lastDays}") public FeeReportDto getFeeReport(@PathVariable Pubkey pubkey, @PathVariable int lastDays) { - return FeeReportDto.createFromModel(feeService.getFeeReportForPeer(pubkey, Period.ofDays(lastDays))); + return FeeReportDto.createFromModel(feeService.getFeeReportForPeer(pubkey, Duration.ofDays(lastDays))); } private List toSortedList(Set channels) { diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java index afff6682..12914b0f 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/NodeControllerTest.java @@ -17,6 +17,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.time.Duration; import java.time.Period; import java.util.List; import java.util.Set; @@ -115,7 +116,7 @@ class NodeControllerTest { @Test void getFeeReportLastDays() { - when(feeService.getFeeReportForPeer(PUBKEY, Period.ofDays(123))).thenReturn(FEE_REPORT); + when(feeService.getFeeReportForPeer(PUBKEY, Duration.ofDays(123))).thenReturn(FEE_REPORT); assertThat(nodeController.getFeeReport(PUBKEY, 123)).isEqualTo(FeeReportDto.createFromModel(FEE_REPORT)); } } \ No newline at end of file