mirror of
https://github.com/aljazceru/lnd-manageJ.git
synced 2026-01-21 23:14:27 +01:00
add basic fee report
This commit is contained in:
@@ -5,6 +5,7 @@ import de.cotto.lndmanagej.model.ChannelIdResolver;
|
||||
import de.cotto.lndmanagej.model.Coins;
|
||||
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.OnChainCostService;
|
||||
import de.cotto.lndmanagej.service.PolicyService;
|
||||
@@ -70,6 +71,9 @@ class ChannelControllerIT {
|
||||
@MockBean
|
||||
private PolicyService policyService;
|
||||
|
||||
@MockBean
|
||||
private FeeService feeService;
|
||||
|
||||
@Test
|
||||
void getBasicInformation_not_found() throws Exception {
|
||||
mockMvc.perform(get(CHANNEL_PREFIX + "/"))
|
||||
@@ -122,6 +126,7 @@ class ChannelControllerIT {
|
||||
when(onChainCostService.getOpenCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(1000)));
|
||||
when(onChainCostService.getCloseCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(2000)));
|
||||
when(balanceService.getBalanceInformation(CHANNEL_ID)).thenReturn(Optional.of(BALANCE_INFORMATION_2));
|
||||
when(feeService.getEarnedFeesForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(1_234));
|
||||
mockMvc.perform(get(DETAILS_PREFIX))
|
||||
.andExpect(jsonPath("$.channelIdShort", is(String.valueOf(CHANNEL_ID.getShortChannelId()))))
|
||||
.andExpect(jsonPath("$.channelIdCompact", is(CHANNEL_ID.getCompactForm())))
|
||||
@@ -151,12 +156,14 @@ class ChannelControllerIT {
|
||||
.andExpect(jsonPath("$.policies.local.feeRatePpm", is(100)))
|
||||
.andExpect(jsonPath("$.policies.local.baseFeeMilliSat", is(10)))
|
||||
.andExpect(jsonPath("$.policies.remote.feeRatePpm", is(222)))
|
||||
.andExpect(jsonPath("$.policies.remote.baseFeeMilliSat", is(0)));
|
||||
.andExpect(jsonPath("$.policies.remote.baseFeeMilliSat", is(0)))
|
||||
.andExpect(jsonPath("$.feeReport.earned", is("1234")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getChannelDetails_closed_channel() throws Exception {
|
||||
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL));
|
||||
when(feeService.getEarnedFeesForChannel(CHANNEL_ID)).thenReturn(Coins.NONE);
|
||||
mockMvc.perform(get(DETAILS_PREFIX))
|
||||
.andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE")))
|
||||
.andExpect(jsonPath("$.closeDetails.height", is(987_654)))
|
||||
@@ -214,4 +221,11 @@ class ChannelControllerIT {
|
||||
.andExpect(jsonPath("$.initiator", is("REMOTE")))
|
||||
.andExpect(jsonPath("$.height", is(987_654)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFeeReport() throws Exception {
|
||||
when(feeService.getEarnedFeesForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(1_234));
|
||||
mockMvc.perform(get(CHANNEL_PREFIX + "/fee-report"))
|
||||
.andExpect(jsonPath("$.earned", is("1234")));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import de.cotto.lndmanagej.controller.dto.BalanceInformationDto;
|
||||
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.ObjectMapperConfiguration;
|
||||
import de.cotto.lndmanagej.controller.dto.OnChainCostsDto;
|
||||
import de.cotto.lndmanagej.controller.dto.PoliciesDto;
|
||||
@@ -19,6 +20,7 @@ import de.cotto.lndmanagej.model.Policies;
|
||||
import de.cotto.lndmanagej.model.Pubkey;
|
||||
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.OnChainCostService;
|
||||
import de.cotto.lndmanagej.service.PolicyService;
|
||||
@@ -31,8 +33,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/channel/{channelId}")
|
||||
@Import(ObjectMapperConfiguration.class)
|
||||
@SuppressWarnings("PMD.ExcessiveImports")
|
||||
@RequestMapping("/api/channel/{channelId}")
|
||||
public class ChannelController {
|
||||
private final ChannelService channelService;
|
||||
private final NodeService nodeService;
|
||||
@@ -40,6 +43,7 @@ public class ChannelController {
|
||||
private final BalanceService balanceService;
|
||||
private final OnChainCostService onChainCostService;
|
||||
private final PolicyService policyService;
|
||||
private final FeeService feeService;
|
||||
|
||||
public ChannelController(
|
||||
ChannelService channelService,
|
||||
@@ -47,14 +51,16 @@ public class ChannelController {
|
||||
BalanceService balanceService,
|
||||
OnChainCostService onChainCostService,
|
||||
PolicyService policyService,
|
||||
FeeService feeService,
|
||||
Metrics metrics
|
||||
) {
|
||||
this.channelService = channelService;
|
||||
this.nodeService = nodeService;
|
||||
this.balanceService = balanceService;
|
||||
this.onChainCostService = onChainCostService;
|
||||
this.metrics = metrics;
|
||||
this.policyService = policyService;
|
||||
this.feeService = feeService;
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
@@ -83,7 +89,8 @@ public class ChannelController {
|
||||
getBalanceInformation(channelId),
|
||||
getOnChainCosts(channelId),
|
||||
getPoliciesForChannel(localChannel),
|
||||
getCloseDetailsForChannel(localChannel)
|
||||
getCloseDetailsForChannel(localChannel),
|
||||
getFeeReportDto(localChannel.getId())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,6 +119,17 @@ public class ChannelController {
|
||||
return new ClosedChannelDetailsDto(closedChannel.getCloseInitiator(), closedChannel.getCloseHeight());
|
||||
}
|
||||
|
||||
@GetMapping("/fee-report")
|
||||
public FeeReportDto getFeeReport(@PathVariable ChannelId channelId) {
|
||||
mark("getFeeReport");
|
||||
return getFeeReportDto(channelId);
|
||||
}
|
||||
|
||||
private FeeReportDto getFeeReportDto(ChannelId channelId) {
|
||||
Coins earned = feeService.getEarnedFeesForChannel(channelId);
|
||||
return new FeeReportDto(earned);
|
||||
}
|
||||
|
||||
private PoliciesDto getPoliciesForChannel(@Nullable LocalChannel channel) {
|
||||
if (channel == null || channel.getStatus().openCloseStatus() != OpenCloseStatus.OPEN) {
|
||||
return PoliciesDto.EMPTY;
|
||||
|
||||
@@ -22,14 +22,16 @@ public record ChannelDetailsDto(
|
||||
BalanceInformationDto balance,
|
||||
OnChainCostsDto onChainCosts,
|
||||
PoliciesDto policies,
|
||||
ClosedChannelDetailsDto closeDetails
|
||||
ClosedChannelDetailsDto closeDetails,
|
||||
FeeReportDto feeReport
|
||||
) {
|
||||
public ChannelDetailsDto(
|
||||
ChannelDto channelDto,
|
||||
String remoteAlias,
|
||||
BalanceInformation balanceInformation,
|
||||
OnChainCostsDto onChainCosts,
|
||||
PoliciesDto policies
|
||||
PoliciesDto policies,
|
||||
FeeReportDto feeReport
|
||||
) {
|
||||
this(
|
||||
channelDto.channelIdShort(),
|
||||
@@ -47,7 +49,8 @@ public record ChannelDetailsDto(
|
||||
BalanceInformationDto.createFrom(balanceInformation),
|
||||
onChainCosts,
|
||||
policies,
|
||||
channelDto.closeDetails()
|
||||
channelDto.closeDetails(),
|
||||
feeReport
|
||||
);
|
||||
}
|
||||
|
||||
@@ -57,14 +60,16 @@ public record ChannelDetailsDto(
|
||||
BalanceInformation balanceInformation,
|
||||
OnChainCostsDto onChainCosts,
|
||||
PoliciesDto policies,
|
||||
ClosedChannelDetailsDto closeDetails
|
||||
ClosedChannelDetailsDto closeDetails,
|
||||
FeeReportDto feeReport
|
||||
) {
|
||||
this(
|
||||
new ChannelDto(localChannel, closeDetails),
|
||||
remoteAlias,
|
||||
balanceInformation,
|
||||
onChainCosts,
|
||||
policies
|
||||
policies,
|
||||
feeReport
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.cotto.lndmanagej.controller.dto;
|
||||
|
||||
import de.cotto.lndmanagej.model.Coins;
|
||||
|
||||
public record FeeReportDto(String earned) {
|
||||
public FeeReportDto(Coins earned) {
|
||||
this(String.valueOf(earned.milliSatoshis()));
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import de.cotto.lndmanagej.controller.dto.BalanceInformationDto;
|
||||
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.OnChainCostsDto;
|
||||
import de.cotto.lndmanagej.controller.dto.PoliciesDto;
|
||||
import de.cotto.lndmanagej.metrics.Metrics;
|
||||
@@ -13,6 +14,7 @@ import de.cotto.lndmanagej.model.Coins;
|
||||
import de.cotto.lndmanagej.model.LocalChannel;
|
||||
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.OnChainCostService;
|
||||
import de.cotto.lndmanagej.service.PolicyService;
|
||||
@@ -47,6 +49,7 @@ class ChannelControllerTest {
|
||||
private static final Coins CLOSE_COSTS = Coins.ofSatoshis(2);
|
||||
private static final OnChainCostsDto ON_CHAIN_COSTS = new OnChainCostsDto(OPEN_COSTS, CLOSE_COSTS);
|
||||
private static final PoliciesDto FEE_CONFIGURATION_DTO = PoliciesDto.createFrom(POLICIES);
|
||||
private static final FeeReportDto FEE_REPORT_DTO = new FeeReportDto(Coins.ofMilliSatoshis(1234));
|
||||
private static final ClosedChannelDetailsDto CLOSED_CHANNEL_DETAILS_DTO =
|
||||
new ClosedChannelDetailsDto(CloseInitiator.REMOTE, 987_654);
|
||||
|
||||
@@ -71,11 +74,15 @@ class ChannelControllerTest {
|
||||
@Mock
|
||||
private PolicyService policyService;
|
||||
|
||||
@Mock
|
||||
private FeeService feeService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
lenient().when(onChainCostService.getOpenCosts(CHANNEL_ID)).thenReturn(Optional.of(OPEN_COSTS));
|
||||
lenient().when(onChainCostService.getCloseCosts(CHANNEL_ID)).thenReturn(Optional.of(CLOSE_COSTS));
|
||||
lenient().when(policyService.getPolicies(CHANNEL_ID)).thenReturn(POLICIES);
|
||||
lenient().when(feeService.getEarnedFeesForChannel(CHANNEL_ID)).thenReturn(Coins.ofMilliSatoshis(1_234));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -114,7 +121,8 @@ class ChannelControllerTest {
|
||||
LOCAL_OPEN_CHANNEL.getBalanceInformation(),
|
||||
ON_CHAIN_COSTS,
|
||||
FEE_CONFIGURATION_DTO,
|
||||
ClosedChannelDetailsDto.UNKNOWN
|
||||
ClosedChannelDetailsDto.UNKNOWN,
|
||||
FEE_REPORT_DTO
|
||||
);
|
||||
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
|
||||
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL));
|
||||
@@ -133,7 +141,8 @@ class ChannelControllerTest {
|
||||
LOCAL_OPEN_CHANNEL_PRIVATE.getBalanceInformation(),
|
||||
ON_CHAIN_COSTS,
|
||||
FEE_CONFIGURATION_DTO,
|
||||
ClosedChannelDetailsDto.UNKNOWN
|
||||
ClosedChannelDetailsDto.UNKNOWN,
|
||||
FEE_REPORT_DTO
|
||||
);
|
||||
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
|
||||
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE));
|
||||
@@ -201,6 +210,13 @@ class ChannelControllerTest {
|
||||
.isThrownBy(() -> channelController.getCloseDetails(CHANNEL_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFeeReport() {
|
||||
when(feeService.getEarnedFeesForChannel(CHANNEL_ID)).thenReturn(Coins.ofSatoshis(123));
|
||||
assertThat(channelController.getFeeReport(CHANNEL_ID)).isEqualTo(new FeeReportDto(Coins.ofSatoshis(123)));
|
||||
verify(metrics).mark(argThat(name -> name.endsWith(".getFeeReport")));
|
||||
}
|
||||
|
||||
private ChannelDetailsDto mockForChannelWithoutPolicies(
|
||||
LocalChannel channel,
|
||||
String closeInitiator,
|
||||
@@ -215,7 +231,8 @@ class ChannelControllerTest {
|
||||
BalanceInformation.EMPTY,
|
||||
ON_CHAIN_COSTS,
|
||||
PoliciesDto.EMPTY,
|
||||
new ClosedChannelDetailsDto(closeInitiator, closeHeight)
|
||||
new ClosedChannelDetailsDto(closeInitiator, closeHeight),
|
||||
FEE_REPORT_DTO
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@ class ChannelDetailsDtoTest {
|
||||
BALANCE_INFORMATION,
|
||||
ON_CHAIN_COSTS,
|
||||
PoliciesDto.EMPTY,
|
||||
CLOSE_DETAILS
|
||||
CLOSE_DETAILS,
|
||||
new FeeReportDto(Coins.ofMilliSatoshis(1234))
|
||||
);
|
||||
|
||||
@Test
|
||||
@@ -82,7 +83,8 @@ class ChannelDetailsDtoTest {
|
||||
BALANCE_INFORMATION,
|
||||
ON_CHAIN_COSTS,
|
||||
PoliciesDto.EMPTY,
|
||||
CLOSE_DETAILS
|
||||
CLOSE_DETAILS,
|
||||
new FeeReportDto(Coins.ofMilliSatoshis(1234))
|
||||
);
|
||||
ChannelStatusDto channelStatusDto =
|
||||
ChannelStatusDto.createFrom(new ChannelStatus(false, true, false, OPEN));
|
||||
@@ -99,6 +101,11 @@ class ChannelDetailsDtoTest {
|
||||
assertThat(CHANNEL_DETAILS_DTO.balance()).isEqualTo(BalanceInformationDto.createFrom(BALANCE_INFORMATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
void feeReport() {
|
||||
assertThat(CHANNEL_DETAILS_DTO.feeReport()).isEqualTo(new FeeReportDto(Coins.ofMilliSatoshis(1_234)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void onChainCosts() {
|
||||
assertThat(CHANNEL_DETAILS_DTO.onChainCosts()).isEqualTo(ON_CHAIN_COSTS);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
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 FeeReportDtoTest {
|
||||
@Test
|
||||
void earned() {
|
||||
assertThat(new FeeReportDto(Coins.ofMilliSatoshis(1_234)).earned()).isEqualTo("1234");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user