mirror of
https://github.com/aljazceru/lnd-manageJ.git
synced 2026-01-21 23:14:27 +01:00
do not query dao for channels closed a long time ago
This commit is contained in:
@@ -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<CacheKey, FeeReport> cacheForOpenChannels;
|
||||
private final LoadingCache<CacheKey, FeeReport> 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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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<ForwardingEvent> getEventsWithOutgoingChannel(ChannelId channelId, Period maxAge);
|
||||
List<ForwardingEvent> getEventsWithOutgoingChannel(ChannelId channelId, Duration maxAge);
|
||||
|
||||
List<ForwardingEvent> getEventsWithIncomingChannel(ChannelId channelId, Period maxAge);
|
||||
List<ForwardingEvent> getEventsWithIncomingChannel(ChannelId channelId, Duration maxAge);
|
||||
}
|
||||
|
||||
@@ -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<ForwardingEvent> getEventsWithOutgoingChannel(ChannelId channelId, Period maxAge) {
|
||||
public List<ForwardingEvent> getEventsWithOutgoingChannel(ChannelId channelId, Duration maxAge) {
|
||||
return repository.findByChannelOutgoingAndTimestampGreaterThan(
|
||||
channelId.getShortChannelId(),
|
||||
getAfterEpochMilliSeconds(maxAge)
|
||||
@@ -46,7 +46,7 @@ public class ForwardingEventsDaoImpl implements ForwardingEventsDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ForwardingEvent> getEventsWithIncomingChannel(ChannelId channelId, Period maxAge) {
|
||||
public List<ForwardingEvent> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -102,7 +102,7 @@ class CoopClosedChannelTest {
|
||||
|
||||
@Test
|
||||
void getCloseHeight() {
|
||||
assertThat(CLOSED_CHANNEL.getCloseHeight()).isEqualTo(987_654);
|
||||
assertThat(CLOSED_CHANNEL.getCloseHeight()).isEqualTo(600_000);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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<ChannelId> toSortedList(Set<? extends Channel> channels) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user