Get rid of Capability ordinals

github.com/AlDanial/cloc v 1.80  T=0.19 s (5.3 files/s, 5.3 lines/s)
-------------------------------------------------------------------------------
                             files          blank        comment           code
-------------------------------------------------------------------------------
 same                            0              0            913           3405
 modified                       28              0              6            145
 added                           1             18             36             58
 removed                         0              9              3            103
-------------------------------------------------------------------------------
This commit is contained in:
Florian Reimair 2019-02-25 09:31:41 +01:00
parent 92b91ba391
commit 00872427de
No known key found for this signature in database
GPG key ID: 7EA8CA324B6E5633
29 changed files with 264 additions and 268 deletions

View file

@ -17,55 +17,87 @@
package bisq.common.app;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.Setter;
/**
* hold a set of capabilities and offers appropriate comparison methods.
*
* @author Florian Reimair
*/
public class Capabilities {
// We can define here special features the client is supporting.
// Useful for updates to new versions where a new data type would break backwards compatibility or to
// limit a node to certain behaviour and roles like the seed nodes.
// We don't use the Enum in any serialized data, as changes in the enum would break backwards compatibility. We use the ordinal integer instead.
// Sequence in the enum must not be changed (append only).
public enum Capability {
TRADE_STATISTICS,
TRADE_STATISTICS_2,
ACCOUNT_AGE_WITNESS,
SEED_NODE,
DAO_FULL_NODE,
PROPOSAL,
BLIND_VOTE,
ACK_MSG,
BSQ_BLOCK
/**
* The global set of capabilities, i.e. the capabilities if the local app.
*/
public static final Capabilities app = new Capabilities();
protected final Set<Capability> capabilities = new HashSet<>();
public Capabilities(Capability... capabilities) {
this(Arrays.asList(capabilities));
}
// Application need to set supported capabilities at startup
@Getter
@Setter
private static List<Integer> supportedCapabilities = new ArrayList<>();
public static void addCapability(int capability) {
supportedCapabilities.add(capability);
public Capabilities(Capabilities capabilities) {
this(capabilities.capabilities);
}
public static boolean isCapabilitySupported(final List<Integer> requiredItems, final List<Integer> supportedItems) {
if (requiredItems != null && !requiredItems.isEmpty()) {
if (supportedItems != null && !supportedItems.isEmpty()) {
List<Integer> matches = new ArrayList<>();
for (int requiredItem : requiredItems) {
matches.addAll(supportedItems.stream()
.filter(supportedItem -> requiredItem == supportedItem)
.collect(Collectors.toList()));
public Capabilities(Collection<Capability> capabilities) {
this.capabilities.addAll(capabilities);
}
return matches.size() == requiredItems.size();
} else {
return false;
public void resetCapabilities(Capability... capabilities) {
resetCapabilities(Arrays.asList(capabilities));
}
} else {
return true;
public void resetCapabilities(Capabilities capabilities) {
resetCapabilities(capabilities.capabilities);
}
public void resetCapabilities(Collection<Capability> capabilities) {
this.capabilities.clear();
this.capabilities.addAll(capabilities);
}
public boolean isCapabilitySupported(final Set<Capability> requiredItems) {
return capabilities.containsAll(requiredItems);
}
public boolean isCapabilitySupported(final Capabilities capabilities) {
return isCapabilitySupported(capabilities.capabilities);
}
public boolean hasCapabilities() {
return !capabilities.isEmpty();
}
/**
* helper for protobuffer stuff
*
* @param capabilities
* @return int list of Capability ordinals
*/
public static List<Integer> toIntList(Capabilities capabilities) {
return capabilities.capabilities.stream().map(capability -> capability.ordinal()).sorted().collect(Collectors.toList());
}
/**
* helper for protobuffer stuff
*
* @param capabilities a list of Capability ordinals
* @return a {@link Capabilities} object
*/
public static Capabilities fromIntList(List<Integer> capabilities) {
return new Capabilities(capabilities.stream().map(integer -> Capability.values()[integer]).collect(Collectors.toSet()));
}
@Override
public String toString() {
return Arrays.toString(Capabilities.toIntList(this).toArray());
}
}

View file

@ -0,0 +1,35 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.common.app;
// We can define here special features the client is supporting.
// Useful for updates to new versions where a new data type would break backwards compatibility or to
// limit a node to certain behaviour and roles like the seed nodes.
// We don't use the Enum in any serialized data, as changes in the enum would break backwards compatibility. We use the ordinal integer instead.
// Sequence in the enum must not be changed (append only).
public enum Capability {
TRADE_STATISTICS,
TRADE_STATISTICS_2,
ACCOUNT_AGE_WITNESS,
SEED_NODE,
DAO_FULL_NODE,
PROPOSAL,
BLIND_VOTE,
ACK_MSG,
BSQ_BLOCK
}

View file

@ -17,39 +17,47 @@
package bisq.common.app;
import java.util.Arrays;
import java.util.HashSet;
import org.junit.Test;
import static bisq.common.app.Capability.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CapabilitiesTest {
@Test
public void testVersionNumber() {
// if required are null or empty its true
assertTrue(Capabilities.isCapabilitySupported(null, null));
assertTrue(Capabilities.isCapabilitySupported(null, Arrays.asList()));
assertTrue(Capabilities.isCapabilitySupported(null, Arrays.asList(0)));
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), null));
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), Arrays.asList()));
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), Arrays.asList(0)));
public void testNoCapabilitiesAvailable() {
Capabilities DUT = new Capabilities();
// required are not null and not empty but supported is null or empty its false
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), null));
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList()));
assertTrue(DUT.isCapabilitySupported(new HashSet<>()));
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE)));
}
@Test
public void testO() {
Capabilities DUT = new Capabilities(TRADE_STATISTICS);
assertTrue(DUT.isCapabilitySupported(new HashSet<>()));
}
@Test
public void testSingleMatch() {
Capabilities DUT = new Capabilities(TRADE_STATISTICS);
// single match
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0)));
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(1), Arrays.asList(0)));
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1)));
assertTrue(DUT.isCapabilitySupported(new Capabilities(TRADE_STATISTICS)));
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE)));
}
// multi match
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0, 1)));
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1, 2)));
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0, 1)));
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(1, 0)));
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0)));
@Test
public void testMultiMatch() {
Capabilities DUT = new Capabilities(TRADE_STATISTICS, TRADE_STATISTICS_2);
assertTrue(DUT.isCapabilitySupported(new Capabilities(TRADE_STATISTICS)));
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE)));
assertTrue(DUT.isCapabilitySupported(new Capabilities(TRADE_STATISTICS, TRADE_STATISTICS_2)));
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE, TRADE_STATISTICS_2)));
}
}

View file

@ -29,6 +29,7 @@ import bisq.network.p2p.seed.SeedNodeRepository;
import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import javax.inject.Inject;
@ -164,22 +165,20 @@ public final class RepublishGovernanceDataHandler {
}
private void connectToAnyFullNode() {
List<Integer> required = new ArrayList<>(Collections.singletonList(
Capabilities.Capability.DAO_FULL_NODE.ordinal()
));
Capabilities required = new Capabilities(Capability.DAO_FULL_NODE);
List<Peer> list = peerManager.getLivePeers(null).stream()
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
.filter(peer -> peer.isCapabilitySupported(required))
.collect(Collectors.toList());
if (list.isEmpty())
list = peerManager.getReportedPeers().stream()
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
.filter(peer -> peer.isCapabilitySupported(required))
.collect(Collectors.toList());
if (list.isEmpty())
list = peerManager.getPersistedPeers().stream()
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
.filter(peer -> peer.isCapabilitySupported(required))
.collect(Collectors.toList());
if (!list.isEmpty()) {

View file

@ -21,15 +21,12 @@ import bisq.network.p2p.DirectMessage;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.app.Version;
import bisq.common.proto.network.NetworkEnvelope;
import io.bisq.generated.protobuffer.PB;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@ -62,10 +59,8 @@ public final class RepublishGovernanceDataRequest extends NetworkEnvelope implem
}
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.DAO_FULL_NODE.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.DAO_FULL_NODE);
}
@Override

View file

@ -25,6 +25,7 @@ import bisq.network.p2p.storage.payload.DateTolerantPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.crypto.Hash;
import bisq.common.proto.persistable.PersistableEnvelope;
import bisq.common.util.Utilities;
@ -33,10 +34,7 @@ import io.bisq.generated.protobuffer.PB;
import com.google.protobuf.ByteString;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.EqualsAndHashCode;
@ -134,10 +132,8 @@ public final class BlindVotePayload implements PersistableNetworkPayload, Persis
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.BLIND_VOTE.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.BLIND_VOTE);
}
@Override

View file

@ -24,6 +24,7 @@ import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.crypto.Hash;
import bisq.common.proto.persistable.PersistableEnvelope;
import bisq.common.util.Utilities;
@ -32,10 +33,6 @@ import io.bisq.generated.protobuffer.PB;
import com.google.protobuf.ByteString;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
@ -111,10 +108,8 @@ public class ProposalPayload implements PersistableNetworkPayload, PersistableEn
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.PROPOSAL.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.PROPOSAL);
}
@Override

View file

@ -25,6 +25,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
import bisq.network.p2p.storage.payload.ProtectedStoragePayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.crypto.Sig;
import bisq.common.proto.persistable.PersistablePayload;
@ -36,9 +37,6 @@ import org.springframework.util.CollectionUtils;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@ -130,10 +128,8 @@ public class TempProposalPayload implements LazyProcessedPayload, ProtectedStora
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.PROPOSAL.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.PROPOSAL);
}

View file

@ -21,15 +21,12 @@ import bisq.network.p2p.DirectMessage;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.app.Version;
import bisq.common.proto.network.NetworkEnvelope;
import io.bisq.generated.protobuffer.PB;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@ -68,10 +65,8 @@ public final class GetBlocksRequest extends NetworkEnvelope implements DirectMes
}
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.DAO_FULL_NODE.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.DAO_FULL_NODE);
}

View file

@ -23,15 +23,12 @@ import bisq.network.p2p.storage.messages.BroadcastMessage;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.app.Version;
import bisq.common.proto.network.NetworkEnvelope;
import io.bisq.generated.protobuffer.PB;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@ -70,9 +67,7 @@ public final class NewBlockBroadcastMessage extends BroadcastMessage implements
}
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.BSQ_BLOCK.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.BSQ_BLOCK);
}
}

View file

@ -25,7 +25,6 @@ import bisq.common.crypto.PubKeyRing;
import io.bisq.generated.protobuffer.PB;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -42,7 +41,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
private final PubKeyRing pubKeyRing;
private final long takersTradePrice;
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
public OfferAvailabilityRequest(String offerId,
PubKeyRing pubKeyRing,
@ -50,7 +49,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
this(offerId,
pubKeyRing,
takersTradePrice,
Capabilities.getSupportedCapabilities(),
Capabilities.app,
Version.getP2PMessageVersion(),
UUID.randomUUID().toString());
}
@ -63,7 +62,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
private OfferAvailabilityRequest(String offerId,
PubKeyRing pubKeyRing,
long takersTradePrice,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion,
@Nullable String uid) {
super(messageVersion, offerId, uid);
@ -79,7 +78,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
.setPubKeyRing(pubKeyRing.toProtoMessage())
.setTakersTradePrice(takersTradePrice);
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
Optional.ofNullable(uid).ifPresent(e -> builder.setUid(uid));
return getNetworkEnvelopeBuilder()
@ -91,7 +90,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
return new OfferAvailabilityRequest(proto.getOfferId(),
PubKeyRing.fromProto(proto.getPubKeyRing()),
proto.getTakersTradePrice(),
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion,
proto.getUid().isEmpty() ? null : proto.getUid());
}

View file

@ -29,7 +29,6 @@ import bisq.common.proto.ProtoUtil;
import io.bisq.generated.protobuffer.PB;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -45,7 +44,7 @@ import javax.annotation.Nullable;
public final class OfferAvailabilityResponse extends OfferMessage implements SupportedCapabilitiesMessage {
private final AvailabilityResult availabilityResult;
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
// Was introduced in v 0.9.0. Might be null if msg received from node with old version
@Nullable
@ -54,7 +53,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
public OfferAvailabilityResponse(String offerId, AvailabilityResult availabilityResult, NodeAddress arbitrator) {
this(offerId,
availabilityResult,
Capabilities.getSupportedCapabilities(),
Capabilities.app,
Version.getP2PMessageVersion(),
UUID.randomUUID().toString(),
arbitrator);
@ -67,7 +66,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
private OfferAvailabilityResponse(String offerId,
AvailabilityResult availabilityResult,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion,
@Nullable String uid,
@Nullable NodeAddress arbitrator) {
@ -83,7 +82,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
.setOfferId(offerId)
.setAvailabilityResult(PB.AvailabilityResult.valueOf(availabilityResult.name()));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
Optional.ofNullable(uid).ifPresent(e -> builder.setUid(uid));
Optional.ofNullable(arbitrator).ifPresent(e -> builder.setArbitrator(arbitrator.toProtoMessage()));
@ -95,7 +94,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
public static OfferAvailabilityResponse fromProto(PB.OfferAvailabilityResponse proto, int messageVersion) {
return new OfferAvailabilityResponse(proto.getOfferId(),
ProtoUtil.enumFromProto(AvailabilityResult.class, proto.getAvailabilityResult().name()),
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion,
proto.getUid().isEmpty() ? null : proto.getUid(),
proto.hasArbitrator() ? NodeAddress.fromProto(proto.getArbitrator()) : null);

View file

@ -24,6 +24,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.proto.persistable.PersistableEnvelope;
import bisq.common.util.Utilities;
@ -31,10 +32,7 @@ import io.bisq.generated.protobuffer.PB;
import com.google.protobuf.ByteString;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.Value;
@ -104,10 +102,8 @@ public class AccountAgeWitness implements LazyProcessedPayload, PersistableNetwo
// Pre 0.6 version don't know the new message type and throw an error which leads to disconnecting the peer.
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.ACCOUNT_AGE_WITNESS.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.ACCOUNT_AGE_WITNESS);
}
@Override

View file

@ -21,29 +21,30 @@ import bisq.core.app.BisqEnvironment;
import bisq.core.dao.DaoOptionKeys;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import java.util.ArrayList;
import java.util.Arrays;
public class CoreNetworkCapabilities {
public static void setSupportedCapabilities(BisqEnvironment bisqEnvironment) {
final ArrayList<Integer> supportedCapabilities = new ArrayList<>(Arrays.asList(
Capabilities.Capability.TRADE_STATISTICS.ordinal(),
Capabilities.Capability.TRADE_STATISTICS_2.ordinal(),
Capabilities.Capability.ACCOUNT_AGE_WITNESS.ordinal(),
Capabilities.Capability.ACK_MSG.ordinal()
final ArrayList<Capability> supportedCapabilities = new ArrayList<>(Arrays.asList(
Capability.TRADE_STATISTICS,
Capability.TRADE_STATISTICS_2,
Capability.ACCOUNT_AGE_WITNESS,
Capability.ACK_MSG
));
if (BisqEnvironment.isDaoActivated(bisqEnvironment)) {
supportedCapabilities.add(Capabilities.Capability.PROPOSAL.ordinal());
supportedCapabilities.add(Capabilities.Capability.BLIND_VOTE.ordinal());
supportedCapabilities.add(Capabilities.Capability.BSQ_BLOCK.ordinal());
supportedCapabilities.add(Capability.PROPOSAL);
supportedCapabilities.add(Capability.BLIND_VOTE);
supportedCapabilities.add(Capability.BSQ_BLOCK);
String isFullDaoNode = bisqEnvironment.getProperty(DaoOptionKeys.FULL_DAO_NODE, String.class, "");
if (isFullDaoNode != null && !isFullDaoNode.isEmpty())
supportedCapabilities.add(Capabilities.Capability.DAO_FULL_NODE.ordinal());
supportedCapabilities.add(Capability.DAO_FULL_NODE);
}
Capabilities.setSupportedCapabilities(supportedCapabilities);
Capabilities.app.resetCapabilities(supportedCapabilities);
}
}

View file

@ -29,6 +29,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.crypto.Hash;
import bisq.common.proto.persistable.PersistableEnvelope;
import bisq.common.util.JsonExclude;
@ -44,10 +45,7 @@ import org.bitcoinj.utils.Fiat;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -215,10 +213,8 @@ public final class TradeStatistics2 implements LazyProcessedPayload, Persistable
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.TRADE_STATISTICS_2.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.TRADE_STATISTICS_2);
}
@Override

View file

@ -21,6 +21,7 @@ import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.network.p2p.storage.payload.ExpirablePayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.app.Version;
import bisq.common.proto.ProtoUtil;
import bisq.common.proto.network.NetworkEnvelope;
@ -28,9 +29,6 @@ import bisq.common.proto.persistable.PersistablePayload;
import io.bisq.generated.protobuffer.PB;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -153,10 +151,8 @@ public final class AckMessage extends NetworkEnvelope implements MailboxMessage,
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<Integer> getRequiredCapabilities() {
return new ArrayList<>(Collections.singletonList(
Capabilities.Capability.ACK_MSG.ordinal()
));
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.ACK_MSG);
}
@Override

View file

@ -619,13 +619,12 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
// it from old versions, so we filter those.
Optional<Peer> optionalPeer = allPeers.stream()
.filter(peer -> peer.getNodeAddress().equals(peersNodeAddress))
.filter(peer -> peer.getSupportedCapabilities() != null)
.filter(peer -> !peer.getSupportedCapabilities().isEmpty())
.filter(peer -> peer.hasCapabilities())
.findAny();
if (optionalPeer.isPresent()) {
Peer peer = optionalPeer.get();
boolean result = Connection.isCapabilityRequired(message) &&
!Connection.isCapabilitySupported((CapabilityRequiringPayload) message, peer.getSupportedCapabilities());
!peer.isCapabilitySupported(((CapabilityRequiringPayload) message).getRequiredCapabilities());
if (result)
log.warn("We don't send the message because the peer does not support the required capability. " +

View file

@ -17,11 +17,11 @@
package bisq.network.p2p;
import java.util.List;
import bisq.common.app.Capabilities;
import javax.annotation.Nullable;
public interface SupportedCapabilitiesMessage {
@Nullable
List<Integer> getSupportedCapabilities();
Capabilities getSupportedCapabilities();
}

View file

@ -310,26 +310,17 @@ public class Connection implements MessageListener {
private boolean isCapabilitySupported(Proto msg) {
if (msg instanceof AddDataMessage) {
final ProtectedStoragePayload protectedStoragePayload = (((AddDataMessage) msg).getProtectedStorageEntry()).getProtectedStoragePayload();
return protectedStoragePayload instanceof CapabilityRequiringPayload && isCapabilitySupported((CapabilityRequiringPayload) protectedStoragePayload);
return protectedStoragePayload instanceof CapabilityRequiringPayload && sharedModel.isCapabilitySupported(((CapabilityRequiringPayload) protectedStoragePayload).getRequiredCapabilities());
} else if (msg instanceof AddPersistableNetworkPayloadMessage) {
final PersistableNetworkPayload persistableNetworkPayload = ((AddPersistableNetworkPayloadMessage) msg).getPersistableNetworkPayload();
return persistableNetworkPayload instanceof CapabilityRequiringPayload && isCapabilitySupported((CapabilityRequiringPayload) persistableNetworkPayload);
return persistableNetworkPayload instanceof CapabilityRequiringPayload && sharedModel.isCapabilitySupported(((CapabilityRequiringPayload) persistableNetworkPayload).getRequiredCapabilities());
} else {
return msg instanceof CapabilityRequiringPayload && isCapabilitySupported((CapabilityRequiringPayload) msg);
return msg instanceof CapabilityRequiringPayload && sharedModel.isCapabilitySupported(((CapabilityRequiringPayload) msg).getRequiredCapabilities());
}
}
private boolean isCapabilitySupported(CapabilityRequiringPayload payload) {
return isCapabilitySupported(payload, sharedModel.getSupportedCapabilities());
}
public static boolean isCapabilitySupported(CapabilityRequiringPayload payload, List<Integer> supportedCapabilities) {
final List<Integer> requiredCapabilities = payload.getRequiredCapabilities();
return Capabilities.isCapabilitySupported(requiredCapabilities, supportedCapabilities);
}
@Nullable
public List<Integer> getSupportedCapabilities() {
public Capabilities getSupportedCapabilities() {
return sharedModel.getSupportedCapabilities();
}
@ -601,7 +592,7 @@ public class Connection implements MessageListener {
* Holds all shared data between Connection and InputHandler
* Runs in same thread as Connection
*/
private static class SharedModel {
private static class SharedModel extends Capabilities {
private static final Logger log = LoggerFactory.getLogger(SharedModel.class);
private final Connection connection;
@ -612,9 +603,6 @@ public class Connection implements MessageListener {
private volatile boolean stopped;
private CloseConnectionReason closeConnectionReason;
private RuleViolation ruleViolation;
@Nullable
private List<Integer> supportedCapabilities;
SharedModel(Connection connection, Socket socket) {
this.connection = connection;
@ -654,18 +642,8 @@ public class Connection implements MessageListener {
}
@Nullable
public List<Integer> getSupportedCapabilities() {
return supportedCapabilities;
}
@SuppressWarnings("NullableProblems")
public void setSupportedCapabilities(List<Integer> supportedCapabilities) {
this.supportedCapabilities = supportedCapabilities;
connection.capabilitiesListeners.forEach(l -> {
SupportedCapabilitiesListener supportedCapabilitiesListener = l.get();
if (supportedCapabilitiesListener != null)
supportedCapabilitiesListener.onChanged(supportedCapabilities);
});
public Capabilities getSupportedCapabilities() {
return new Capabilities(capabilities);
}
public void handleConnectionException(Throwable e) {
@ -727,7 +705,7 @@ public class Connection implements MessageListener {
",\n stopped=" + stopped +
",\n closeConnectionReason=" + closeConnectionReason +
",\n ruleViolation=" + ruleViolation +
",\n supportedCapabilities=" + supportedCapabilities +
",\n supportedCapabilities=" + capabilities +
"\n}";
}
}
@ -895,8 +873,8 @@ public class Connection implements MessageListener {
return;
}
if (sharedModel.getSupportedCapabilities() == null && networkEnvelope instanceof SupportedCapabilitiesMessage)
sharedModel.setSupportedCapabilities(((SupportedCapabilitiesMessage) networkEnvelope).getSupportedCapabilities());
if (networkEnvelope instanceof SupportedCapabilitiesMessage)
sharedModel.resetCapabilities(((SupportedCapabilitiesMessage) networkEnvelope).getSupportedCapabilities());
if (networkEnvelope instanceof CloseConnectionMessage) {
// If we get a CloseConnectionMessage we shut down

View file

@ -17,8 +17,8 @@
package bisq.network.p2p.network;
import java.util.List;
import bisq.common.app.Capabilities;
public interface SupportedCapabilitiesListener {
void onChanged(List<Integer> supportedCapabilities);
void onChanged(Capabilities supportedCapabilities);
}

View file

@ -32,6 +32,7 @@ import bisq.network.p2p.seed.SeedNodeRepository;
import bisq.common.Clock;
import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.Capabilities;
import bisq.common.proto.persistable.PersistedDataHost;
import bisq.common.proto.persistable.PersistenceProtoResolver;
import bisq.common.storage.Storage;
@ -175,7 +176,7 @@ public class PeerManager implements ConnectionListener, PersistedDataHost {
PeerList persistedPeerList = storage.initAndGetPersistedWithFileName("PeerList", 1000);
if (persistedPeerList != null) {
long peersWithNoCapabilitiesSet = persistedPeerList.getList().stream()
.filter(e -> e.getSupportedCapabilities().isEmpty())
.filter(e -> e.hasCapabilities())
.mapToInt(e -> 1)
.count();
if (peersWithNoCapabilitiesSet > 100) {
@ -659,19 +660,18 @@ public class PeerManager implements ConnectionListener, PersistedDataHost {
// filter(connection -> connection.getPeersNodeAddressOptional().isPresent())
return networkNode.getConfirmedConnections().stream()
.map((Connection connection) -> {
List<Integer> supportedCapabilities = connection.getSupportedCapabilities();
Capabilities supportedCapabilities = connection.getSupportedCapabilities();
// If we have a new connection the supportedCapabilities is empty.
// We lookup if we have already stored the supportedCapabilities at the persisted or reported peers
// and if so we use that.
if (supportedCapabilities == null || supportedCapabilities.isEmpty()) {
if (!supportedCapabilities.hasCapabilities()) {
Set<Peer> allPeers = new HashSet<>(getPersistedPeers());
allPeers.addAll(getReportedPeers());
supportedCapabilities = allPeers.stream().filter(peer -> peer.getNodeAddress().equals(connection.getPeersNodeAddressOptional().get()))
.filter(peer -> !peer.getSupportedCapabilities().isEmpty())
.findAny()
.map(Peer::getSupportedCapabilities)
.filter(list -> !list.isEmpty())
.orElse(new ArrayList<>());
Optional<Peer> ourPeer = allPeers.stream().filter(peer -> peer.getNodeAddress().equals(connection.getPeersNodeAddressOptional().get()))
.filter(peer -> !peer.hasCapabilities())
.findAny();
if(ourPeer.isPresent())
supportedCapabilities = new Capabilities(ourPeer.get());
}
Peer peer = new Peer(connection.getPeersNodeAddressOptional().get(), supportedCapabilities);
connection.addWeakCapabilitiesListener(peer);

View file

@ -31,6 +31,7 @@ import bisq.network.p2p.storage.payload.ProtectedStoragePayload;
import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.Capabilities;
import bisq.common.util.Utilities;
import com.google.common.util.concurrent.FutureCallback;
@ -38,7 +39,6 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -159,25 +159,15 @@ public class GetDataRequestHandler {
final ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
boolean doAdd = false;
if (protectedStoragePayload instanceof CapabilityRequiringPayload) {
final List<Integer> requiredCapabilities = ((CapabilityRequiringPayload) protectedStoragePayload).getRequiredCapabilities();
final List<Integer> supportedCapabilities = connection.getSupportedCapabilities();
if (supportedCapabilities != null) {
for (int messageCapability : requiredCapabilities) {
for (int connectionCapability : supportedCapabilities) {
if (messageCapability == connectionCapability) {
final Capabilities supportedCapabilities = connection.getSupportedCapabilities();
if (supportedCapabilities.hasCapabilities()) {
if (supportedCapabilities.isCapabilitySupported(((CapabilityRequiringPayload) protectedStoragePayload).getRequiredCapabilities()))
doAdd = true;
break;
}
}
}
if (!doAdd)
else
log.debug("We do not send the message to the peer because he does not support the required capability for that message type.\n" +
"Required capabilities is: " + requiredCapabilities.toString() + "\n" +
"Supported capabilities is: " + supportedCapabilities.toString() + "\n" +
"storagePayload is: " + Utilities.toTruncatedString(protectedStoragePayload));
} else {
log.debug("We do not send the message to the peer because he uses an old version which does not support capabilities.\n" +
"Required capabilities is: " + requiredCapabilities.toString() + "\n" +
"storagePayload is: " + Utilities.toTruncatedString(protectedStoragePayload));
}
} else {

View file

@ -31,7 +31,6 @@ import bisq.common.proto.network.NetworkProtoResolver;
import io.bisq.generated.protobuffer.PB;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -57,7 +56,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
private final int requestNonce;
private final boolean isGetUpdatedDataResponse;
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
public GetDataResponse(Set<ProtectedStorageEntry> dataSet,
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
@ -67,7 +66,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
persistableNetworkPayloadSet,
requestNonce,
isGetUpdatedDataResponse,
Capabilities.getSupportedCapabilities(),
Capabilities.app,
Version.getP2PMessageVersion());
}
@ -79,7 +78,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
int requestNonce,
boolean isGetUpdatedDataResponse,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion) {
super(messageVersion);
@ -106,7 +105,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
.setRequestNonce(requestNonce)
.setIsGetUpdatedDataResponse(isGetUpdatedDataResponse);
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
Optional.ofNullable(persistableNetworkPayloadSet).ifPresent(set -> builder.addAllPersistableNetworkPayloadItems(set.stream()
.map(PersistableNetworkPayload::toProtoMessage)
.collect(Collectors.toList())));
@ -134,7 +133,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
persistableNetworkPayloadSet,
proto.getRequestNonce(),
proto.getIsGetUpdatedDataResponse(),
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion);
}
}

View file

@ -28,7 +28,6 @@ import io.bisq.generated.protobuffer.PB;
import com.google.protobuf.ByteString;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -45,11 +44,11 @@ import javax.annotation.Nullable;
public final class PreliminaryGetDataRequest extends GetDataRequest implements AnonymousMessage, SupportedCapabilitiesMessage {
// ordinals of enum
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
public PreliminaryGetDataRequest(int nonce,
Set<byte[]> excludedKeys) {
this(nonce, excludedKeys, Capabilities.getSupportedCapabilities(), Version.getP2PMessageVersion());
this(nonce, excludedKeys, Capabilities.app, Version.getP2PMessageVersion());
}
@ -59,7 +58,7 @@ public final class PreliminaryGetDataRequest extends GetDataRequest implements A
private PreliminaryGetDataRequest(int nonce,
Set<byte[]> excludedKeys,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion) {
super(messageVersion, nonce, excludedKeys);
@ -74,7 +73,7 @@ public final class PreliminaryGetDataRequest extends GetDataRequest implements A
.map(ByteString::copyFrom)
.collect(Collectors.toList()));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
return getNetworkEnvelopeBuilder()
.setPreliminaryGetDataRequest(builder)
@ -84,7 +83,7 @@ public final class PreliminaryGetDataRequest extends GetDataRequest implements A
public static PreliminaryGetDataRequest fromProto(PB.PreliminaryGetDataRequest proto, int messageVersion) {
return new PreliminaryGetDataRequest(proto.getNonce(),
ProtoUtil.byteSetFromProtoByteStringList(proto.getExcludedKeysList()),
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion);
}
}

View file

@ -20,14 +20,13 @@ package bisq.network.p2p.peers.peerexchange;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.network.SupportedCapabilitiesListener;
import bisq.common.app.Capabilities;
import bisq.common.proto.network.NetworkPayload;
import bisq.common.proto.persistable.PersistablePayload;
import io.bisq.generated.protobuffer.PB;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@ -39,31 +38,28 @@ import javax.annotation.Nullable;
@Getter
@EqualsAndHashCode(exclude = {"date"}) // failedConnectionAttempts is transient and therefore excluded anyway
@Slf4j
public final class Peer implements NetworkPayload, PersistablePayload, SupportedCapabilitiesListener {
public final class Peer extends Capabilities implements NetworkPayload, PersistablePayload, SupportedCapabilitiesListener {
private static final int MAX_FAILED_CONNECTION_ATTEMPTS = 5;
private final NodeAddress nodeAddress;
private final long date;
// Added in v. 0.7.1
@Setter
private List<Integer> supportedCapabilities = new ArrayList<>();
@Setter
transient private int failedConnectionAttempts = 0;
public Peer(NodeAddress nodeAddress, @Nullable List<Integer> supportedCapabilities) {
this(nodeAddress, new Date().getTime(),
supportedCapabilities == null ? new ArrayList<>() : supportedCapabilities);
public Peer(NodeAddress nodeAddress, @Nullable Capabilities supportedCapabilities) {
this(nodeAddress, new Date().getTime(), supportedCapabilities);
}
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
private Peer(NodeAddress nodeAddress, long date, List<Integer> supportedCapabilities) {
private Peer(NodeAddress nodeAddress, long date, Capabilities supportedCapabilities) {
super(supportedCapabilities);
this.nodeAddress = nodeAddress;
this.date = date;
this.supportedCapabilities = supportedCapabilities;
}
@Override
@ -71,15 +67,14 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
return PB.Peer.newBuilder()
.setNodeAddress(nodeAddress.toProtoMessage())
.setDate(date)
.addAllSupportedCapabilities(supportedCapabilities)
.addAllSupportedCapabilities(Capabilities.toIntList(this))
.build();
}
public static Peer fromProto(PB.Peer proto) {
return new Peer(NodeAddress.fromProto(proto.getNodeAddress()),
proto.getDate(),
proto.getSupportedCapabilitiesList().isEmpty() ?
new ArrayList<>() : new ArrayList<>(proto.getSupportedCapabilitiesList()));
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()));
}
@ -100,9 +95,9 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
}
@Override
public void onChanged(List<Integer> supportedCapabilities) {
if (supportedCapabilities != null && !supportedCapabilities.isEmpty())
this.supportedCapabilities = supportedCapabilities;
public void onChanged(Capabilities supportedCapabilities) {
if (supportedCapabilities.hasCapabilities())
resetCapabilities(supportedCapabilities);
}
@ -110,7 +105,7 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
public String toString() {
return "Peer{" +
"\n nodeAddress=" + nodeAddress +
",\n supportedCapabilities=" + supportedCapabilities +
",\n supportedCapabilities=" + capabilities +
",\n failedConnectionAttempts=" + failedConnectionAttempts +
",\n date=" + date +
"\n}";

View file

@ -29,7 +29,6 @@ import bisq.common.proto.network.NetworkEnvelope;
import io.bisq.generated.protobuffer.PB;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -48,10 +47,10 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
private final int nonce;
private final Set<Peer> reportedPeers;
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
public GetPeersRequest(NodeAddress senderNodeAddress, int nonce, Set<Peer> reportedPeers) {
this(senderNodeAddress, nonce, reportedPeers, Capabilities.getSupportedCapabilities(), Version.getP2PMessageVersion());
this(senderNodeAddress, nonce, reportedPeers, Capabilities.app, Version.getP2PMessageVersion());
}
@ -62,7 +61,7 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
private GetPeersRequest(NodeAddress senderNodeAddress,
int nonce,
Set<Peer> reportedPeers,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion) {
super(messageVersion);
checkNotNull(senderNodeAddress, "senderNodeAddress must not be null at GetPeersRequest");
@ -81,7 +80,7 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
.map(Peer::toProtoMessage)
.collect(Collectors.toList()));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
return getNetworkEnvelopeBuilder()
.setGetPeersRequest(builder)
@ -94,7 +93,7 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
new HashSet<>(proto.getReportedPeersList().stream()
.map(Peer::fromProto)
.collect(Collectors.toSet())),
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion);
}
}

View file

@ -28,7 +28,6 @@ import bisq.common.proto.network.NetworkEnvelope;
import io.bisq.generated.protobuffer.PB;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -44,10 +43,10 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
private final int requestNonce;
private final Set<Peer> reportedPeers;
@Nullable
private final List<Integer> supportedCapabilities;
private final Capabilities supportedCapabilities;
public GetPeersResponse(int requestNonce, Set<Peer> reportedPeers) {
this(requestNonce, reportedPeers, Capabilities.getSupportedCapabilities(), Version.getP2PMessageVersion());
this(requestNonce, reportedPeers, Capabilities.app, Version.getP2PMessageVersion());
}
@ -57,7 +56,7 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
private GetPeersResponse(int requestNonce,
Set<Peer> reportedPeers,
@Nullable List<Integer> supportedCapabilities,
@Nullable Capabilities supportedCapabilities,
int messageVersion) {
super(messageVersion);
this.requestNonce = requestNonce;
@ -73,7 +72,7 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
.map(Peer::toProtoMessage)
.collect(Collectors.toList()));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
return getNetworkEnvelopeBuilder()
.setGetPeersResponse(builder)
@ -86,12 +85,12 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
.map(peer -> {
NodeAddress nodeAddress = new NodeAddress(peer.getNodeAddress().getHostName(),
peer.getNodeAddress().getPort());
return new Peer(nodeAddress, peer.getSupportedCapabilitiesList());
return new Peer(nodeAddress, Capabilities.fromIntList(peer.getSupportedCapabilitiesList()));
})
.collect(Collectors.toCollection(HashSet::new));
return new GetPeersResponse(proto.getRequestNonce(),
reportedPeers,
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
messageVersion);
}
}

View file

@ -17,10 +17,9 @@
package bisq.network.p2p.storage.payload;
import bisq.common.app.Capabilities;
import bisq.common.proto.network.NetworkPayload;
import java.util.List;
/**
* Used for payloads which requires certain capability.
* <p/>
@ -31,5 +30,5 @@ public interface CapabilityRequiringPayload extends NetworkPayload {
/**
* @return Capabilities the other node need to support to receive that message
*/
List<Integer> getRequiredCapabilities();
Capabilities getRequiredCapabilities();
}

View file

@ -25,10 +25,13 @@ import bisq.core.app.misc.ModuleForAppWithP2p;
import bisq.common.UserThread;
import bisq.common.app.AppModule;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.setup.CommonSetup;
import joptsimple.OptionSet;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -60,7 +63,10 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
@Override
protected void addCapabilities() {
Capabilities.addCapability(Capabilities.Capability.SEED_NODE.ordinal());
// TODO got even worse after refactoring
List<Integer> current = Capabilities.toIntList(Capabilities.app);
current.add(Capability.SEED_NODE.ordinal());
Capabilities.app.resetCapabilities(Capabilities.fromIntList(current));
}
@Override