add private status to channel details

This commit is contained in:
Carsten Otto
2021-11-19 18:18:52 +01:00
parent e938c2d8a0
commit 256c1cc42a
13 changed files with 126 additions and 35 deletions

View File

@@ -12,7 +12,7 @@ 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.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_PRIVATE;
import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static org.hamcrest.core.Is.is;
@@ -47,10 +47,11 @@ class ChannelDetailsControllerIT {
@Test
void getChannelDetails() throws Exception {
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL));
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE));
mockMvc.perform(get(CHANNEL_PREFIX + "/details"))
.andExpect(jsonPath("$.channelId", is(String.valueOf(CHANNEL_ID.getShortChannelId()))))
.andExpect(jsonPath("$.remotePubkey", is(PUBKEY_2.toString())))
.andExpect(jsonPath("$.remoteAlias", is(ALIAS_2)));
.andExpect(jsonPath("$.remoteAlias", is(ALIAS_2)))
.andExpect(jsonPath("$.private", is(true)));
}
}

View File

@@ -34,6 +34,7 @@ public class ChannelDetailsController {
}
Pubkey remotePubkey = localChannel.getRemotePubkey();
String remoteAlias = nodeService.getAlias(remotePubkey);
return new ChannelDetailsDto(localChannel.getId(), remotePubkey, remoteAlias);
boolean privateChannel = localChannel.isPrivateChannel();
return new ChannelDetailsDto(localChannel.getId(), remotePubkey, remoteAlias, privateChannel);
}
}

View File

@@ -1,5 +1,6 @@
package de.cotto.lndmanagej.controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import de.cotto.lndmanagej.model.ChannelId;
@@ -8,6 +9,7 @@ import de.cotto.lndmanagej.model.Pubkey;
public record ChannelDetailsDto(
@JsonSerialize(using = ToStringSerializer.class) ChannelId channelId,
@JsonSerialize(using = ToStringSerializer.class) Pubkey remotePubkey,
String remoteAlias
String remoteAlias,
@JsonProperty("private") boolean privateChannel
) {
}

View File

@@ -13,6 +13,7 @@ import java.util.Optional;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_PRIVATE;
import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static org.assertj.core.api.Assertions.assertThat;
@@ -43,11 +44,21 @@ class ChannelDetailsControllerTest {
@Test
void getDetails() throws NotFoundException {
ChannelDetailsDto expectedDetails = new ChannelDetailsDto(CHANNEL_ID, PUBKEY_2, ALIAS_2);
ChannelDetailsDto expectedDetails = new ChannelDetailsDto(CHANNEL_ID, PUBKEY_2, ALIAS_2, false);
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL));
assertThat(channelDetailsController.getDetails(CHANNEL_ID)).isEqualTo(expectedDetails);
verify(metrics).mark(argThat(name -> name.endsWith(".getDetails")));
}
@Test
void getDetails_private() throws NotFoundException {
ChannelDetailsDto expectedDetails = new ChannelDetailsDto(CHANNEL_ID, PUBKEY_2, ALIAS_2, true);
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE));
assertThat(channelDetailsController.getDetails(CHANNEL_ID)).isEqualTo(expectedDetails);
verify(metrics).mark(argThat(name -> name.endsWith(".getDetails")));
}
}

View File

@@ -143,8 +143,8 @@ class TransactionBackgroundLoaderTest {
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL
);
LOCAL,
false);
LocalOpenChannel channel2 = new LocalOpenChannel(
CHANNEL_ID_2,
CHANNEL_POINT_2,
@@ -152,8 +152,8 @@ class TransactionBackgroundLoaderTest {
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL
);
LOCAL,
false);
LocalOpenChannel channel3 = new LocalOpenChannel(
CHANNEL_ID_3,
CHANNEL_POINT_3,
@@ -161,8 +161,8 @@ class TransactionBackgroundLoaderTest {
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL
);
LOCAL,
false);
when(channelService.getOpenChannels()).thenReturn(Set.of(channel1, channel2, channel3));
String unknownHash = CHANNEL_POINT_3.getTransactionHash();
when(transactionService.isUnknown(any())).thenReturn(false);

View File

@@ -123,7 +123,8 @@ public class GrpcChannels extends GrpcChannelsBase {
ownPubkey,
Pubkey.create(lndChannel.getRemotePubkey()),
balanceInformation,
getOpenInitiator(lndChannel)
getOpenInitiator(lndChannel),
lndChannel.getPrivate()
);
}

View File

@@ -32,6 +32,7 @@ import static de.cotto.lndmanagej.model.ForceClosingChannelFixtures.FORCE_CLOSIN
import static de.cotto.lndmanagej.model.ForceClosingChannelFixtures.HTLC_OUTPOINT;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_2;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_PRIVATE;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static de.cotto.lndmanagej.model.WaitingCloseChannelFixtures.WAITING_CLOSE_CHANNEL;
@@ -66,12 +67,20 @@ class GrpcChannelsTest {
@Test
void getChannels() {
when(grpcService.getChannels()).thenReturn(List.of(
channel(CHANNEL_ID, true),
channel(CHANNEL_ID_2, false)
channel(CHANNEL_ID, true, false),
channel(CHANNEL_ID_2, false, false)
));
assertThat(grpcChannels.getChannels()).containsExactlyInAnyOrder(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_2);
}
@Test
void getChannels_private() {
when(grpcService.getChannels()).thenReturn(List.of(
channel(CHANNEL_ID, true, true)
));
assertThat(grpcChannels.getChannels()).containsExactlyInAnyOrder(LOCAL_OPEN_CHANNEL_PRIVATE);
}
@Test
void getForceClosingChannels_both_resolved() {
when(channelIdResolver.resolveFromChannelPoint(CHANNEL_POINT)).thenReturn(Optional.of(CHANNEL_ID));
@@ -119,8 +128,8 @@ class GrpcChannelsTest {
@Test
void getChannel() {
when(grpcService.getChannels()).thenReturn(List.of(
channel(CHANNEL_ID_2, false),
channel(CHANNEL_ID, true)
channel(CHANNEL_ID_2, false, false),
channel(CHANNEL_ID, true, false)
));
assertThat(grpcChannels.getChannel(CHANNEL_ID)).contains(LOCAL_OPEN_CHANNEL);
}
@@ -130,7 +139,7 @@ class GrpcChannelsTest {
assertThat(grpcChannels.getChannel(CHANNEL_ID)).isEmpty();
}
private Channel channel(ChannelId channelId, boolean isInitiator) {
private Channel channel(ChannelId channelId, boolean isInitiator, boolean isPrivate) {
ChannelConstraints localConstraints = ChannelConstraints.newBuilder()
.setChanReserveSat(BALANCE_INFORMATION.localReserve().satoshis())
.build();
@@ -147,6 +156,7 @@ class GrpcChannelsTest {
.setLocalConstraints(localConstraints)
.setRemoteConstraints(remoteConstraints)
.setInitiator(isInitiator)
.setPrivate(isPrivate)
.build();
}

View File

@@ -14,7 +14,7 @@ public class ClosedOrClosingChannel extends LocalChannel {
String closeTransactionHash,
OpenInitiator openInitiator
) {
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator);
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator, false);
this.closeTransactionHash = closeTransactionHash;
}

View File

@@ -5,6 +5,7 @@ import java.util.Objects;
public class LocalChannel extends Channel {
private final Pubkey remotePubkey;
private final OpenInitiator openInitiator;
private final boolean privateChannel;
protected LocalChannel(
ChannelId channelId,
@@ -12,17 +13,27 @@ public class LocalChannel extends Channel {
Coins capacity,
Pubkey ownPubkey,
Pubkey remotePubkey,
OpenInitiator openInitiator
OpenInitiator openInitiator,
boolean privateChannel
) {
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey);
this.remotePubkey = remotePubkey;
this.openInitiator = openInitiator;
this.privateChannel = privateChannel;
}
public Pubkey getRemotePubkey() {
return remotePubkey;
}
public OpenInitiator getOpenInitiator() {
return openInitiator;
}
public boolean isPrivateChannel() {
return privateChannel;
}
@Override
@SuppressWarnings("CPD-START")
public boolean equals(Object other) {
@@ -36,15 +47,13 @@ public class LocalChannel extends Channel {
return false;
}
LocalChannel that = (LocalChannel) other;
return Objects.equals(remotePubkey, that.remotePubkey) && openInitiator == that.openInitiator;
return privateChannel == that.privateChannel
&& Objects.equals(remotePubkey, that.remotePubkey)
&& openInitiator == that.openInitiator;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), remotePubkey, openInitiator);
}
public OpenInitiator getOpenInitiator() {
return openInitiator;
return Objects.hash(super.hashCode(), remotePubkey, openInitiator, privateChannel);
}
}

View File

@@ -12,9 +12,10 @@ public class LocalOpenChannel extends LocalChannel {
Pubkey ownPubkey,
Pubkey remotePubkey,
BalanceInformation balanceInformation,
OpenInitiator openInitiator
OpenInitiator openInitiator,
boolean isPrivate
) {
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator);
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator, isPrivate);
this.balanceInformation = balanceInformation;
}

View File

@@ -9,6 +9,6 @@ public class WaitingCloseChannel extends LocalChannel {
Pubkey remotePubkey,
OpenInitiator openInitiator
) {
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator);
super(channelId, channelPoint, capacity, ownPubkey, remotePubkey, openInitiator, false);
}
}

View File

@@ -25,8 +25,16 @@ class LocalOpenChannelTest {
@Test
void getRemotePubkey_swapped() {
LocalOpenChannel localOpenChannel =
new LocalOpenChannel(CHANNEL_ID, CHANNEL_POINT, CAPACITY, PUBKEY_2, PUBKEY, BALANCE_INFORMATION, LOCAL);
LocalOpenChannel localOpenChannel = new LocalOpenChannel(
CHANNEL_ID,
CHANNEL_POINT,
CAPACITY,
PUBKEY_2,
PUBKEY,
BALANCE_INFORMATION,
LOCAL,
false
);
assertThat(localOpenChannel.getRemotePubkey()).isEqualTo(PUBKEY);
}

View File

@@ -16,11 +16,58 @@ import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_3;
public class LocalOpenChannelFixtures {
public static final LocalOpenChannel LOCAL_OPEN_CHANNEL =
new LocalOpenChannel(CHANNEL_ID, CHANNEL_POINT, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION, LOCAL);
new LocalOpenChannel(
CHANNEL_ID,
CHANNEL_POINT,
CAPACITY,
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL,
false
);
public static final LocalOpenChannel LOCAL_OPEN_CHANNEL_PRIVATE =
new LocalOpenChannel(
CHANNEL_ID,
CHANNEL_POINT,
CAPACITY,
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL,
true
);
public static final LocalOpenChannel LOCAL_OPEN_CHANNEL_2 =
new LocalOpenChannel(CHANNEL_ID_2, CHANNEL_POINT, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION, REMOTE);
new LocalOpenChannel(
CHANNEL_ID_2,
CHANNEL_POINT,
CAPACITY,
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
REMOTE,
false
);
public static final LocalOpenChannel LOCAL_OPEN_CHANNEL_3 =
new LocalOpenChannel(CHANNEL_ID_3, CHANNEL_POINT, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION, LOCAL);
new LocalOpenChannel(
CHANNEL_ID_3,
CHANNEL_POINT,
CAPACITY,
PUBKEY,
PUBKEY_2,
BALANCE_INFORMATION,
LOCAL,
false
);
public static final LocalOpenChannel LOCAL_OPEN_CHANNEL_TO_NODE_3 =
new LocalOpenChannel(CHANNEL_ID_4, CHANNEL_POINT, CAPACITY_2, PUBKEY, PUBKEY_3, BALANCE_INFORMATION, LOCAL);
new LocalOpenChannel(
CHANNEL_ID_4,
CHANNEL_POINT,
CAPACITY_2,
PUBKEY,
PUBKEY_3,
BALANCE_INFORMATION,
LOCAL,
false
);
}