mirror of
https://github.com/bisq-network/bisq.git
synced 2025-03-03 18:56:59 +01:00
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:
parent
92b91ba391
commit
00872427de
29 changed files with 264 additions and 268 deletions
|
@ -17,55 +17,87 @@
|
||||||
|
|
||||||
package bisq.common.app;
|
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.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
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 {
|
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.
|
* The global set of capabilities, i.e. the capabilities if the local app.
|
||||||
// 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 static final Capabilities app = new Capabilities();
|
||||||
public enum Capability {
|
|
||||||
TRADE_STATISTICS,
|
protected final Set<Capability> capabilities = new HashSet<>();
|
||||||
TRADE_STATISTICS_2,
|
|
||||||
ACCOUNT_AGE_WITNESS,
|
public Capabilities(Capability... capabilities) {
|
||||||
SEED_NODE,
|
this(Arrays.asList(capabilities));
|
||||||
DAO_FULL_NODE,
|
|
||||||
PROPOSAL,
|
|
||||||
BLIND_VOTE,
|
|
||||||
ACK_MSG,
|
|
||||||
BSQ_BLOCK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application need to set supported capabilities at startup
|
public Capabilities(Capabilities capabilities) {
|
||||||
@Getter
|
this(capabilities.capabilities);
|
||||||
@Setter
|
|
||||||
private static List<Integer> supportedCapabilities = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void addCapability(int capability) {
|
|
||||||
supportedCapabilities.add(capability);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCapabilitySupported(final List<Integer> requiredItems, final List<Integer> supportedItems) {
|
public Capabilities(Collection<Capability> capabilities) {
|
||||||
if (requiredItems != null && !requiredItems.isEmpty()) {
|
this.capabilities.addAll(capabilities);
|
||||||
if (supportedItems != null && !supportedItems.isEmpty()) {
|
}
|
||||||
List<Integer> matches = new ArrayList<>();
|
|
||||||
for (int requiredItem : requiredItems) {
|
public void resetCapabilities(Capability... capabilities) {
|
||||||
matches.addAll(supportedItems.stream()
|
resetCapabilities(Arrays.asList(capabilities));
|
||||||
.filter(supportedItem -> requiredItem == supportedItem)
|
}
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
public void resetCapabilities(Capabilities capabilities) {
|
||||||
return matches.size() == requiredItems.size();
|
resetCapabilities(capabilities.capabilities);
|
||||||
} else {
|
}
|
||||||
return false;
|
|
||||||
}
|
public void resetCapabilities(Collection<Capability> capabilities) {
|
||||||
} else {
|
this.capabilities.clear();
|
||||||
return true;
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
common/src/main/java/bisq/common/app/Capability.java
Normal file
35
common/src/main/java/bisq/common/app/Capability.java
Normal 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
|
||||||
|
}
|
|
@ -17,39 +17,47 @@
|
||||||
|
|
||||||
package bisq.common.app;
|
package bisq.common.app;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static bisq.common.app.Capability.*;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class CapabilitiesTest {
|
public class CapabilitiesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVersionNumber() {
|
public void testNoCapabilitiesAvailable() {
|
||||||
// if required are null or empty its true
|
Capabilities DUT = new Capabilities();
|
||||||
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)));
|
|
||||||
|
|
||||||
// required are not null and not empty but supported is null or empty its false
|
assertTrue(DUT.isCapabilitySupported(new HashSet<>()));
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), null));
|
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE)));
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList()));
|
}
|
||||||
|
|
||||||
|
@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
|
// single match
|
||||||
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0)));
|
assertTrue(DUT.isCapabilitySupported(new Capabilities(TRADE_STATISTICS)));
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(1), Arrays.asList(0)));
|
assertFalse(DUT.isCapabilitySupported(new Capabilities(SEED_NODE)));
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1)));
|
}
|
||||||
|
|
||||||
// multi match
|
@Test
|
||||||
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0, 1)));
|
public void testMultiMatch() {
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1, 2)));
|
Capabilities DUT = new Capabilities(TRADE_STATISTICS, TRADE_STATISTICS_2);
|
||||||
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0, 1)));
|
|
||||||
assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(1, 0)));
|
assertTrue(DUT.isCapabilitySupported(new Capabilities(TRADE_STATISTICS)));
|
||||||
assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0)));
|
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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import bisq.network.p2p.seed.SeedNodeRepository;
|
||||||
import bisq.common.Timer;
|
import bisq.common.Timer;
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@ -164,22 +165,20 @@ public final class RepublishGovernanceDataHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connectToAnyFullNode() {
|
private void connectToAnyFullNode() {
|
||||||
List<Integer> required = new ArrayList<>(Collections.singletonList(
|
Capabilities required = new Capabilities(Capability.DAO_FULL_NODE);
|
||||||
Capabilities.Capability.DAO_FULL_NODE.ordinal()
|
|
||||||
));
|
|
||||||
|
|
||||||
List<Peer> list = peerManager.getLivePeers(null).stream()
|
List<Peer> list = peerManager.getLivePeers(null).stream()
|
||||||
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
|
.filter(peer -> peer.isCapabilitySupported(required))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
list = peerManager.getReportedPeers().stream()
|
list = peerManager.getReportedPeers().stream()
|
||||||
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
|
.filter(peer -> peer.isCapabilitySupported(required))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
list = peerManager.getPersistedPeers().stream()
|
list = peerManager.getPersistedPeers().stream()
|
||||||
.filter(peer -> Capabilities.isCapabilitySupported(required, peer.getSupportedCapabilities()))
|
.filter(peer -> peer.isCapabilitySupported(required))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
|
|
|
@ -21,15 +21,12 @@ import bisq.network.p2p.DirectMessage;
|
||||||
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.app.Version;
|
import bisq.common.app.Version;
|
||||||
import bisq.common.proto.network.NetworkEnvelope;
|
import bisq.common.proto.network.NetworkEnvelope;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -62,10 +59,8 @@ public final class RepublishGovernanceDataRequest extends NetworkEnvelope implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.DAO_FULL_NODE);
|
||||||
Capabilities.Capability.DAO_FULL_NODE.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,6 +25,7 @@ import bisq.network.p2p.storage.payload.DateTolerantPayload;
|
||||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.crypto.Hash;
|
import bisq.common.crypto.Hash;
|
||||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
@ -33,10 +34,7 @@ import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
@ -134,10 +132,8 @@ public final class BlindVotePayload implements PersistableNetworkPayload, Persis
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.BLIND_VOTE);
|
||||||
Capabilities.Capability.BLIND_VOTE.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.crypto.Hash;
|
import bisq.common.crypto.Hash;
|
||||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
@ -32,10 +33,6 @@ import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@ -111,10 +108,8 @@ public class ProposalPayload implements PersistableNetworkPayload, PersistableEn
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.PROPOSAL);
|
||||||
Capabilities.Capability.PROPOSAL.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,6 +25,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
|
||||||
import bisq.network.p2p.storage.payload.ProtectedStoragePayload;
|
import bisq.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.crypto.Sig;
|
import bisq.common.crypto.Sig;
|
||||||
import bisq.common.proto.persistable.PersistablePayload;
|
import bisq.common.proto.persistable.PersistablePayload;
|
||||||
|
|
||||||
|
@ -36,9 +37,6 @@ import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -130,10 +128,8 @@ public class TempProposalPayload implements LazyProcessedPayload, ProtectedStora
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.PROPOSAL);
|
||||||
Capabilities.Capability.PROPOSAL.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,15 +21,12 @@ import bisq.network.p2p.DirectMessage;
|
||||||
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.app.Version;
|
import bisq.common.app.Version;
|
||||||
import bisq.common.proto.network.NetworkEnvelope;
|
import bisq.common.proto.network.NetworkEnvelope;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -68,10 +65,8 @@ public final class GetBlocksRequest extends NetworkEnvelope implements DirectMes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.DAO_FULL_NODE);
|
||||||
Capabilities.Capability.DAO_FULL_NODE.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,12 @@ import bisq.network.p2p.storage.messages.BroadcastMessage;
|
||||||
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.app.Version;
|
import bisq.common.app.Version;
|
||||||
import bisq.common.proto.network.NetworkEnvelope;
|
import bisq.common.proto.network.NetworkEnvelope;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -70,9 +67,7 @@ public final class NewBlockBroadcastMessage extends BroadcastMessage implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.BSQ_BLOCK);
|
||||||
Capabilities.Capability.BSQ_BLOCK.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import bisq.common.crypto.PubKeyRing;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
|
||||||
private final PubKeyRing pubKeyRing;
|
private final PubKeyRing pubKeyRing;
|
||||||
private final long takersTradePrice;
|
private final long takersTradePrice;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<Integer> supportedCapabilities;
|
private final Capabilities supportedCapabilities;
|
||||||
|
|
||||||
public OfferAvailabilityRequest(String offerId,
|
public OfferAvailabilityRequest(String offerId,
|
||||||
PubKeyRing pubKeyRing,
|
PubKeyRing pubKeyRing,
|
||||||
|
@ -50,7 +49,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
|
||||||
this(offerId,
|
this(offerId,
|
||||||
pubKeyRing,
|
pubKeyRing,
|
||||||
takersTradePrice,
|
takersTradePrice,
|
||||||
Capabilities.getSupportedCapabilities(),
|
Capabilities.app,
|
||||||
Version.getP2PMessageVersion(),
|
Version.getP2PMessageVersion(),
|
||||||
UUID.randomUUID().toString());
|
UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
@ -63,7 +62,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
|
||||||
private OfferAvailabilityRequest(String offerId,
|
private OfferAvailabilityRequest(String offerId,
|
||||||
PubKeyRing pubKeyRing,
|
PubKeyRing pubKeyRing,
|
||||||
long takersTradePrice,
|
long takersTradePrice,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion,
|
int messageVersion,
|
||||||
@Nullable String uid) {
|
@Nullable String uid) {
|
||||||
super(messageVersion, offerId, uid);
|
super(messageVersion, offerId, uid);
|
||||||
|
@ -79,7 +78,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
|
||||||
.setPubKeyRing(pubKeyRing.toProtoMessage())
|
.setPubKeyRing(pubKeyRing.toProtoMessage())
|
||||||
.setTakersTradePrice(takersTradePrice);
|
.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));
|
Optional.ofNullable(uid).ifPresent(e -> builder.setUid(uid));
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder()
|
return getNetworkEnvelopeBuilder()
|
||||||
|
@ -91,7 +90,7 @@ public final class OfferAvailabilityRequest extends OfferMessage implements Supp
|
||||||
return new OfferAvailabilityRequest(proto.getOfferId(),
|
return new OfferAvailabilityRequest(proto.getOfferId(),
|
||||||
PubKeyRing.fromProto(proto.getPubKeyRing()),
|
PubKeyRing.fromProto(proto.getPubKeyRing()),
|
||||||
proto.getTakersTradePrice(),
|
proto.getTakersTradePrice(),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion,
|
messageVersion,
|
||||||
proto.getUid().isEmpty() ? null : proto.getUid());
|
proto.getUid().isEmpty() ? null : proto.getUid());
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import bisq.common.proto.ProtoUtil;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ import javax.annotation.Nullable;
|
||||||
public final class OfferAvailabilityResponse extends OfferMessage implements SupportedCapabilitiesMessage {
|
public final class OfferAvailabilityResponse extends OfferMessage implements SupportedCapabilitiesMessage {
|
||||||
private final AvailabilityResult availabilityResult;
|
private final AvailabilityResult availabilityResult;
|
||||||
@Nullable
|
@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
|
// Was introduced in v 0.9.0. Might be null if msg received from node with old version
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -54,7 +53,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||||
public OfferAvailabilityResponse(String offerId, AvailabilityResult availabilityResult, NodeAddress arbitrator) {
|
public OfferAvailabilityResponse(String offerId, AvailabilityResult availabilityResult, NodeAddress arbitrator) {
|
||||||
this(offerId,
|
this(offerId,
|
||||||
availabilityResult,
|
availabilityResult,
|
||||||
Capabilities.getSupportedCapabilities(),
|
Capabilities.app,
|
||||||
Version.getP2PMessageVersion(),
|
Version.getP2PMessageVersion(),
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
arbitrator);
|
arbitrator);
|
||||||
|
@ -67,7 +66,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||||
|
|
||||||
private OfferAvailabilityResponse(String offerId,
|
private OfferAvailabilityResponse(String offerId,
|
||||||
AvailabilityResult availabilityResult,
|
AvailabilityResult availabilityResult,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion,
|
int messageVersion,
|
||||||
@Nullable String uid,
|
@Nullable String uid,
|
||||||
@Nullable NodeAddress arbitrator) {
|
@Nullable NodeAddress arbitrator) {
|
||||||
|
@ -83,7 +82,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||||
.setOfferId(offerId)
|
.setOfferId(offerId)
|
||||||
.setAvailabilityResult(PB.AvailabilityResult.valueOf(availabilityResult.name()));
|
.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(uid).ifPresent(e -> builder.setUid(uid));
|
||||||
Optional.ofNullable(arbitrator).ifPresent(e -> builder.setArbitrator(arbitrator.toProtoMessage()));
|
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) {
|
public static OfferAvailabilityResponse fromProto(PB.OfferAvailabilityResponse proto, int messageVersion) {
|
||||||
return new OfferAvailabilityResponse(proto.getOfferId(),
|
return new OfferAvailabilityResponse(proto.getOfferId(),
|
||||||
ProtoUtil.enumFromProto(AvailabilityResult.class, proto.getAvailabilityResult().name()),
|
ProtoUtil.enumFromProto(AvailabilityResult.class, proto.getAvailabilityResult().name()),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion,
|
messageVersion,
|
||||||
proto.getUid().isEmpty() ? null : proto.getUid(),
|
proto.getUid().isEmpty() ? null : proto.getUid(),
|
||||||
proto.hasArbitrator() ? NodeAddress.fromProto(proto.getArbitrator()) : null);
|
proto.hasArbitrator() ? NodeAddress.fromProto(proto.getArbitrator()) : null);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
|
||||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
|
||||||
|
@ -31,10 +32,7 @@ import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import lombok.Value;
|
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.
|
// Pre 0.6 version don't know the new message type and throw an error which leads to disconnecting the peer.
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.ACCOUNT_AGE_WITNESS);
|
||||||
Capabilities.Capability.ACCOUNT_AGE_WITNESS.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,29 +21,30 @@ import bisq.core.app.BisqEnvironment;
|
||||||
import bisq.core.dao.DaoOptionKeys;
|
import bisq.core.dao.DaoOptionKeys;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class CoreNetworkCapabilities {
|
public class CoreNetworkCapabilities {
|
||||||
public static void setSupportedCapabilities(BisqEnvironment bisqEnvironment) {
|
public static void setSupportedCapabilities(BisqEnvironment bisqEnvironment) {
|
||||||
final ArrayList<Integer> supportedCapabilities = new ArrayList<>(Arrays.asList(
|
final ArrayList<Capability> supportedCapabilities = new ArrayList<>(Arrays.asList(
|
||||||
Capabilities.Capability.TRADE_STATISTICS.ordinal(),
|
Capability.TRADE_STATISTICS,
|
||||||
Capabilities.Capability.TRADE_STATISTICS_2.ordinal(),
|
Capability.TRADE_STATISTICS_2,
|
||||||
Capabilities.Capability.ACCOUNT_AGE_WITNESS.ordinal(),
|
Capability.ACCOUNT_AGE_WITNESS,
|
||||||
Capabilities.Capability.ACK_MSG.ordinal()
|
Capability.ACK_MSG
|
||||||
));
|
));
|
||||||
|
|
||||||
if (BisqEnvironment.isDaoActivated(bisqEnvironment)) {
|
if (BisqEnvironment.isDaoActivated(bisqEnvironment)) {
|
||||||
supportedCapabilities.add(Capabilities.Capability.PROPOSAL.ordinal());
|
supportedCapabilities.add(Capability.PROPOSAL);
|
||||||
supportedCapabilities.add(Capabilities.Capability.BLIND_VOTE.ordinal());
|
supportedCapabilities.add(Capability.BLIND_VOTE);
|
||||||
supportedCapabilities.add(Capabilities.Capability.BSQ_BLOCK.ordinal());
|
supportedCapabilities.add(Capability.BSQ_BLOCK);
|
||||||
|
|
||||||
String isFullDaoNode = bisqEnvironment.getProperty(DaoOptionKeys.FULL_DAO_NODE, String.class, "");
|
String isFullDaoNode = bisqEnvironment.getProperty(DaoOptionKeys.FULL_DAO_NODE, String.class, "");
|
||||||
if (isFullDaoNode != null && !isFullDaoNode.isEmpty())
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import bisq.network.p2p.storage.payload.LazyProcessedPayload;
|
||||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.crypto.Hash;
|
import bisq.common.crypto.Hash;
|
||||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||||
import bisq.common.util.JsonExclude;
|
import bisq.common.util.JsonExclude;
|
||||||
|
@ -44,10 +45,7 @@ import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -215,10 +213,8 @@ public final class TradeStatistics2 implements LazyProcessedPayload, Persistable
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.TRADE_STATISTICS_2);
|
||||||
Capabilities.Capability.TRADE_STATISTICS_2.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
import bisq.network.p2p.storage.payload.ExpirablePayload;
|
import bisq.network.p2p.storage.payload.ExpirablePayload;
|
||||||
|
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.app.Version;
|
import bisq.common.app.Version;
|
||||||
import bisq.common.proto.ProtoUtil;
|
import bisq.common.proto.ProtoUtil;
|
||||||
import bisq.common.proto.network.NetworkEnvelope;
|
import bisq.common.proto.network.NetworkEnvelope;
|
||||||
|
@ -28,9 +29,6 @@ import bisq.common.proto.persistable.PersistablePayload;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
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.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -153,10 +151,8 @@ public final class AckMessage extends NetworkEnvelope implements MailboxMessage,
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getRequiredCapabilities() {
|
public Capabilities getRequiredCapabilities() {
|
||||||
return new ArrayList<>(Collections.singletonList(
|
return new Capabilities(Capability.ACK_MSG);
|
||||||
Capabilities.Capability.ACK_MSG.ordinal()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -619,13 +619,12 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
// it from old versions, so we filter those.
|
// it from old versions, so we filter those.
|
||||||
Optional<Peer> optionalPeer = allPeers.stream()
|
Optional<Peer> optionalPeer = allPeers.stream()
|
||||||
.filter(peer -> peer.getNodeAddress().equals(peersNodeAddress))
|
.filter(peer -> peer.getNodeAddress().equals(peersNodeAddress))
|
||||||
.filter(peer -> peer.getSupportedCapabilities() != null)
|
.filter(peer -> peer.hasCapabilities())
|
||||||
.filter(peer -> !peer.getSupportedCapabilities().isEmpty())
|
|
||||||
.findAny();
|
.findAny();
|
||||||
if (optionalPeer.isPresent()) {
|
if (optionalPeer.isPresent()) {
|
||||||
Peer peer = optionalPeer.get();
|
Peer peer = optionalPeer.get();
|
||||||
boolean result = Connection.isCapabilityRequired(message) &&
|
boolean result = Connection.isCapabilityRequired(message) &&
|
||||||
!Connection.isCapabilitySupported((CapabilityRequiringPayload) message, peer.getSupportedCapabilities());
|
!peer.isCapabilitySupported(((CapabilityRequiringPayload) message).getRequiredCapabilities());
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
log.warn("We don't send the message because the peer does not support the required capability. " +
|
log.warn("We don't send the message because the peer does not support the required capability. " +
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
package bisq.network.p2p;
|
package bisq.network.p2p;
|
||||||
|
|
||||||
import java.util.List;
|
import bisq.common.app.Capabilities;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public interface SupportedCapabilitiesMessage {
|
public interface SupportedCapabilitiesMessage {
|
||||||
@Nullable
|
@Nullable
|
||||||
List<Integer> getSupportedCapabilities();
|
Capabilities getSupportedCapabilities();
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,26 +310,17 @@ public class Connection implements MessageListener {
|
||||||
private boolean isCapabilitySupported(Proto msg) {
|
private boolean isCapabilitySupported(Proto msg) {
|
||||||
if (msg instanceof AddDataMessage) {
|
if (msg instanceof AddDataMessage) {
|
||||||
final ProtectedStoragePayload protectedStoragePayload = (((AddDataMessage) msg).getProtectedStorageEntry()).getProtectedStoragePayload();
|
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) {
|
} else if (msg instanceof AddPersistableNetworkPayloadMessage) {
|
||||||
final PersistableNetworkPayload persistableNetworkPayload = ((AddPersistableNetworkPayloadMessage) msg).getPersistableNetworkPayload();
|
final PersistableNetworkPayload persistableNetworkPayload = ((AddPersistableNetworkPayloadMessage) msg).getPersistableNetworkPayload();
|
||||||
return persistableNetworkPayload instanceof CapabilityRequiringPayload && isCapabilitySupported((CapabilityRequiringPayload) persistableNetworkPayload);
|
return persistableNetworkPayload instanceof CapabilityRequiringPayload && sharedModel.isCapabilitySupported(((CapabilityRequiringPayload) persistableNetworkPayload).getRequiredCapabilities());
|
||||||
} else {
|
} 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
|
@Nullable
|
||||||
public List<Integer> getSupportedCapabilities() {
|
public Capabilities getSupportedCapabilities() {
|
||||||
return sharedModel.getSupportedCapabilities();
|
return sharedModel.getSupportedCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +592,7 @@ public class Connection implements MessageListener {
|
||||||
* Holds all shared data between Connection and InputHandler
|
* Holds all shared data between Connection and InputHandler
|
||||||
* Runs in same thread as Connection
|
* 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 static final Logger log = LoggerFactory.getLogger(SharedModel.class);
|
||||||
|
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
|
@ -612,9 +603,6 @@ public class Connection implements MessageListener {
|
||||||
private volatile boolean stopped;
|
private volatile boolean stopped;
|
||||||
private CloseConnectionReason closeConnectionReason;
|
private CloseConnectionReason closeConnectionReason;
|
||||||
private RuleViolation ruleViolation;
|
private RuleViolation ruleViolation;
|
||||||
@Nullable
|
|
||||||
private List<Integer> supportedCapabilities;
|
|
||||||
|
|
||||||
|
|
||||||
SharedModel(Connection connection, Socket socket) {
|
SharedModel(Connection connection, Socket socket) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
@ -654,18 +642,8 @@ public class Connection implements MessageListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public List<Integer> getSupportedCapabilities() {
|
public Capabilities getSupportedCapabilities() {
|
||||||
return supportedCapabilities;
|
return new Capabilities(capabilities);
|
||||||
}
|
|
||||||
|
|
||||||
@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 void handleConnectionException(Throwable e) {
|
public void handleConnectionException(Throwable e) {
|
||||||
|
@ -727,7 +705,7 @@ public class Connection implements MessageListener {
|
||||||
",\n stopped=" + stopped +
|
",\n stopped=" + stopped +
|
||||||
",\n closeConnectionReason=" + closeConnectionReason +
|
",\n closeConnectionReason=" + closeConnectionReason +
|
||||||
",\n ruleViolation=" + ruleViolation +
|
",\n ruleViolation=" + ruleViolation +
|
||||||
",\n supportedCapabilities=" + supportedCapabilities +
|
",\n supportedCapabilities=" + capabilities +
|
||||||
"\n}";
|
"\n}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -895,8 +873,8 @@ public class Connection implements MessageListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedModel.getSupportedCapabilities() == null && networkEnvelope instanceof SupportedCapabilitiesMessage)
|
if (networkEnvelope instanceof SupportedCapabilitiesMessage)
|
||||||
sharedModel.setSupportedCapabilities(((SupportedCapabilitiesMessage) networkEnvelope).getSupportedCapabilities());
|
sharedModel.resetCapabilities(((SupportedCapabilitiesMessage) networkEnvelope).getSupportedCapabilities());
|
||||||
|
|
||||||
if (networkEnvelope instanceof CloseConnectionMessage) {
|
if (networkEnvelope instanceof CloseConnectionMessage) {
|
||||||
// If we get a CloseConnectionMessage we shut down
|
// If we get a CloseConnectionMessage we shut down
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
package bisq.network.p2p.network;
|
package bisq.network.p2p.network;
|
||||||
|
|
||||||
import java.util.List;
|
import bisq.common.app.Capabilities;
|
||||||
|
|
||||||
public interface SupportedCapabilitiesListener {
|
public interface SupportedCapabilitiesListener {
|
||||||
void onChanged(List<Integer> supportedCapabilities);
|
void onChanged(Capabilities supportedCapabilities);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import bisq.network.p2p.seed.SeedNodeRepository;
|
||||||
import bisq.common.Clock;
|
import bisq.common.Clock;
|
||||||
import bisq.common.Timer;
|
import bisq.common.Timer;
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
|
import bisq.common.app.Capabilities;
|
||||||
import bisq.common.proto.persistable.PersistedDataHost;
|
import bisq.common.proto.persistable.PersistedDataHost;
|
||||||
import bisq.common.proto.persistable.PersistenceProtoResolver;
|
import bisq.common.proto.persistable.PersistenceProtoResolver;
|
||||||
import bisq.common.storage.Storage;
|
import bisq.common.storage.Storage;
|
||||||
|
@ -175,7 +176,7 @@ public class PeerManager implements ConnectionListener, PersistedDataHost {
|
||||||
PeerList persistedPeerList = storage.initAndGetPersistedWithFileName("PeerList", 1000);
|
PeerList persistedPeerList = storage.initAndGetPersistedWithFileName("PeerList", 1000);
|
||||||
if (persistedPeerList != null) {
|
if (persistedPeerList != null) {
|
||||||
long peersWithNoCapabilitiesSet = persistedPeerList.getList().stream()
|
long peersWithNoCapabilitiesSet = persistedPeerList.getList().stream()
|
||||||
.filter(e -> e.getSupportedCapabilities().isEmpty())
|
.filter(e -> e.hasCapabilities())
|
||||||
.mapToInt(e -> 1)
|
.mapToInt(e -> 1)
|
||||||
.count();
|
.count();
|
||||||
if (peersWithNoCapabilitiesSet > 100) {
|
if (peersWithNoCapabilitiesSet > 100) {
|
||||||
|
@ -659,19 +660,18 @@ public class PeerManager implements ConnectionListener, PersistedDataHost {
|
||||||
// filter(connection -> connection.getPeersNodeAddressOptional().isPresent())
|
// filter(connection -> connection.getPeersNodeAddressOptional().isPresent())
|
||||||
return networkNode.getConfirmedConnections().stream()
|
return networkNode.getConfirmedConnections().stream()
|
||||||
.map((Connection connection) -> {
|
.map((Connection connection) -> {
|
||||||
List<Integer> supportedCapabilities = connection.getSupportedCapabilities();
|
Capabilities supportedCapabilities = connection.getSupportedCapabilities();
|
||||||
// If we have a new connection the supportedCapabilities is empty.
|
// 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
|
// We lookup if we have already stored the supportedCapabilities at the persisted or reported peers
|
||||||
// and if so we use that.
|
// and if so we use that.
|
||||||
if (supportedCapabilities == null || supportedCapabilities.isEmpty()) {
|
if (!supportedCapabilities.hasCapabilities()) {
|
||||||
Set<Peer> allPeers = new HashSet<>(getPersistedPeers());
|
Set<Peer> allPeers = new HashSet<>(getPersistedPeers());
|
||||||
allPeers.addAll(getReportedPeers());
|
allPeers.addAll(getReportedPeers());
|
||||||
supportedCapabilities = allPeers.stream().filter(peer -> peer.getNodeAddress().equals(connection.getPeersNodeAddressOptional().get()))
|
Optional<Peer> ourPeer = allPeers.stream().filter(peer -> peer.getNodeAddress().equals(connection.getPeersNodeAddressOptional().get()))
|
||||||
.filter(peer -> !peer.getSupportedCapabilities().isEmpty())
|
.filter(peer -> !peer.hasCapabilities())
|
||||||
.findAny()
|
.findAny();
|
||||||
.map(Peer::getSupportedCapabilities)
|
if(ourPeer.isPresent())
|
||||||
.filter(list -> !list.isEmpty())
|
supportedCapabilities = new Capabilities(ourPeer.get());
|
||||||
.orElse(new ArrayList<>());
|
|
||||||
}
|
}
|
||||||
Peer peer = new Peer(connection.getPeersNodeAddressOptional().get(), supportedCapabilities);
|
Peer peer = new Peer(connection.getPeersNodeAddressOptional().get(), supportedCapabilities);
|
||||||
connection.addWeakCapabilitiesListener(peer);
|
connection.addWeakCapabilitiesListener(peer);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import bisq.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||||
|
|
||||||
import bisq.common.Timer;
|
import bisq.common.Timer;
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
|
import bisq.common.app.Capabilities;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
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 com.google.common.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -159,25 +159,15 @@ public class GetDataRequestHandler {
|
||||||
final ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
|
final ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
|
||||||
boolean doAdd = false;
|
boolean doAdd = false;
|
||||||
if (protectedStoragePayload instanceof CapabilityRequiringPayload) {
|
if (protectedStoragePayload instanceof CapabilityRequiringPayload) {
|
||||||
final List<Integer> requiredCapabilities = ((CapabilityRequiringPayload) protectedStoragePayload).getRequiredCapabilities();
|
final Capabilities supportedCapabilities = connection.getSupportedCapabilities();
|
||||||
final List<Integer> supportedCapabilities = connection.getSupportedCapabilities();
|
if (supportedCapabilities.hasCapabilities()) {
|
||||||
if (supportedCapabilities != null) {
|
if (supportedCapabilities.isCapabilitySupported(((CapabilityRequiringPayload) protectedStoragePayload).getRequiredCapabilities()))
|
||||||
for (int messageCapability : requiredCapabilities) {
|
doAdd = true;
|
||||||
for (int connectionCapability : supportedCapabilities) {
|
else
|
||||||
if (messageCapability == connectionCapability) {
|
|
||||||
doAdd = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!doAdd)
|
|
||||||
log.debug("We do not send the message to the peer because he does not support the required capability for that message type.\n" +
|
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));
|
"storagePayload is: " + Utilities.toTruncatedString(protectedStoragePayload));
|
||||||
} else {
|
} else {
|
||||||
log.debug("We do not send the message to the peer because he uses an old version which does not support capabilities.\n" +
|
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));
|
"storagePayload is: " + Utilities.toTruncatedString(protectedStoragePayload));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,7 +31,6 @@ import bisq.common.proto.network.NetworkProtoResolver;
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -57,7 +56,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
|
||||||
private final int requestNonce;
|
private final int requestNonce;
|
||||||
private final boolean isGetUpdatedDataResponse;
|
private final boolean isGetUpdatedDataResponse;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<Integer> supportedCapabilities;
|
private final Capabilities supportedCapabilities;
|
||||||
|
|
||||||
public GetDataResponse(Set<ProtectedStorageEntry> dataSet,
|
public GetDataResponse(Set<ProtectedStorageEntry> dataSet,
|
||||||
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
|
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
|
||||||
|
@ -67,7 +66,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
|
||||||
persistableNetworkPayloadSet,
|
persistableNetworkPayloadSet,
|
||||||
requestNonce,
|
requestNonce,
|
||||||
isGetUpdatedDataResponse,
|
isGetUpdatedDataResponse,
|
||||||
Capabilities.getSupportedCapabilities(),
|
Capabilities.app,
|
||||||
Version.getP2PMessageVersion());
|
Version.getP2PMessageVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
|
||||||
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
|
@Nullable Set<PersistableNetworkPayload> persistableNetworkPayloadSet,
|
||||||
int requestNonce,
|
int requestNonce,
|
||||||
boolean isGetUpdatedDataResponse,
|
boolean isGetUpdatedDataResponse,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion) {
|
int messageVersion) {
|
||||||
super(messageVersion);
|
super(messageVersion);
|
||||||
|
|
||||||
|
@ -106,7 +105,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
|
||||||
.setRequestNonce(requestNonce)
|
.setRequestNonce(requestNonce)
|
||||||
.setIsGetUpdatedDataResponse(isGetUpdatedDataResponse);
|
.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()
|
Optional.ofNullable(persistableNetworkPayloadSet).ifPresent(set -> builder.addAllPersistableNetworkPayloadItems(set.stream()
|
||||||
.map(PersistableNetworkPayload::toProtoMessage)
|
.map(PersistableNetworkPayload::toProtoMessage)
|
||||||
.collect(Collectors.toList())));
|
.collect(Collectors.toList())));
|
||||||
|
@ -134,7 +133,7 @@ public final class GetDataResponse extends NetworkEnvelope implements SupportedC
|
||||||
persistableNetworkPayloadSet,
|
persistableNetworkPayloadSet,
|
||||||
proto.getRequestNonce(),
|
proto.getRequestNonce(),
|
||||||
proto.getIsGetUpdatedDataResponse(),
|
proto.getIsGetUpdatedDataResponse(),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion);
|
messageVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -45,11 +44,11 @@ import javax.annotation.Nullable;
|
||||||
public final class PreliminaryGetDataRequest extends GetDataRequest implements AnonymousMessage, SupportedCapabilitiesMessage {
|
public final class PreliminaryGetDataRequest extends GetDataRequest implements AnonymousMessage, SupportedCapabilitiesMessage {
|
||||||
// ordinals of enum
|
// ordinals of enum
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<Integer> supportedCapabilities;
|
private final Capabilities supportedCapabilities;
|
||||||
|
|
||||||
public PreliminaryGetDataRequest(int nonce,
|
public PreliminaryGetDataRequest(int nonce,
|
||||||
Set<byte[]> excludedKeys) {
|
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,
|
private PreliminaryGetDataRequest(int nonce,
|
||||||
Set<byte[]> excludedKeys,
|
Set<byte[]> excludedKeys,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion) {
|
int messageVersion) {
|
||||||
super(messageVersion, nonce, excludedKeys);
|
super(messageVersion, nonce, excludedKeys);
|
||||||
|
|
||||||
|
@ -74,7 +73,7 @@ public final class PreliminaryGetDataRequest extends GetDataRequest implements A
|
||||||
.map(ByteString::copyFrom)
|
.map(ByteString::copyFrom)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
|
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder()
|
return getNetworkEnvelopeBuilder()
|
||||||
.setPreliminaryGetDataRequest(builder)
|
.setPreliminaryGetDataRequest(builder)
|
||||||
|
@ -84,7 +83,7 @@ public final class PreliminaryGetDataRequest extends GetDataRequest implements A
|
||||||
public static PreliminaryGetDataRequest fromProto(PB.PreliminaryGetDataRequest proto, int messageVersion) {
|
public static PreliminaryGetDataRequest fromProto(PB.PreliminaryGetDataRequest proto, int messageVersion) {
|
||||||
return new PreliminaryGetDataRequest(proto.getNonce(),
|
return new PreliminaryGetDataRequest(proto.getNonce(),
|
||||||
ProtoUtil.byteSetFromProtoByteStringList(proto.getExcludedKeysList()),
|
ProtoUtil.byteSetFromProtoByteStringList(proto.getExcludedKeysList()),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion);
|
messageVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,13 @@ package bisq.network.p2p.peers.peerexchange;
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.network.p2p.network.SupportedCapabilitiesListener;
|
import bisq.network.p2p.network.SupportedCapabilitiesListener;
|
||||||
|
|
||||||
|
import bisq.common.app.Capabilities;
|
||||||
import bisq.common.proto.network.NetworkPayload;
|
import bisq.common.proto.network.NetworkPayload;
|
||||||
import bisq.common.proto.persistable.PersistablePayload;
|
import bisq.common.proto.persistable.PersistablePayload;
|
||||||
|
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -39,31 +38,28 @@ import javax.annotation.Nullable;
|
||||||
@Getter
|
@Getter
|
||||||
@EqualsAndHashCode(exclude = {"date"}) // failedConnectionAttempts is transient and therefore excluded anyway
|
@EqualsAndHashCode(exclude = {"date"}) // failedConnectionAttempts is transient and therefore excluded anyway
|
||||||
@Slf4j
|
@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 static final int MAX_FAILED_CONNECTION_ATTEMPTS = 5;
|
||||||
|
|
||||||
private final NodeAddress nodeAddress;
|
private final NodeAddress nodeAddress;
|
||||||
private final long date;
|
private final long date;
|
||||||
// Added in v. 0.7.1
|
// Added in v. 0.7.1
|
||||||
@Setter
|
|
||||||
private List<Integer> supportedCapabilities = new ArrayList<>();
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
transient private int failedConnectionAttempts = 0;
|
transient private int failedConnectionAttempts = 0;
|
||||||
|
|
||||||
public Peer(NodeAddress nodeAddress, @Nullable List<Integer> supportedCapabilities) {
|
public Peer(NodeAddress nodeAddress, @Nullable Capabilities supportedCapabilities) {
|
||||||
this(nodeAddress, new Date().getTime(),
|
this(nodeAddress, new Date().getTime(), supportedCapabilities);
|
||||||
supportedCapabilities == null ? new ArrayList<>() : supportedCapabilities);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// PROTO BUFFER
|
// 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.nodeAddress = nodeAddress;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.supportedCapabilities = supportedCapabilities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,15 +67,14 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
|
||||||
return PB.Peer.newBuilder()
|
return PB.Peer.newBuilder()
|
||||||
.setNodeAddress(nodeAddress.toProtoMessage())
|
.setNodeAddress(nodeAddress.toProtoMessage())
|
||||||
.setDate(date)
|
.setDate(date)
|
||||||
.addAllSupportedCapabilities(supportedCapabilities)
|
.addAllSupportedCapabilities(Capabilities.toIntList(this))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Peer fromProto(PB.Peer proto) {
|
public static Peer fromProto(PB.Peer proto) {
|
||||||
return new Peer(NodeAddress.fromProto(proto.getNodeAddress()),
|
return new Peer(NodeAddress.fromProto(proto.getNodeAddress()),
|
||||||
proto.getDate(),
|
proto.getDate(),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ?
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()));
|
||||||
new ArrayList<>() : new ArrayList<>(proto.getSupportedCapabilitiesList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,9 +95,9 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<Integer> supportedCapabilities) {
|
public void onChanged(Capabilities supportedCapabilities) {
|
||||||
if (supportedCapabilities != null && !supportedCapabilities.isEmpty())
|
if (supportedCapabilities.hasCapabilities())
|
||||||
this.supportedCapabilities = supportedCapabilities;
|
resetCapabilities(supportedCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,7 +105,7 @@ public final class Peer implements NetworkPayload, PersistablePayload, Supported
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Peer{" +
|
return "Peer{" +
|
||||||
"\n nodeAddress=" + nodeAddress +
|
"\n nodeAddress=" + nodeAddress +
|
||||||
",\n supportedCapabilities=" + supportedCapabilities +
|
",\n supportedCapabilities=" + capabilities +
|
||||||
",\n failedConnectionAttempts=" + failedConnectionAttempts +
|
",\n failedConnectionAttempts=" + failedConnectionAttempts +
|
||||||
",\n date=" + date +
|
",\n date=" + date +
|
||||||
"\n}";
|
"\n}";
|
||||||
|
|
|
@ -29,7 +29,6 @@ import bisq.common.proto.network.NetworkEnvelope;
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -48,10 +47,10 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
|
||||||
private final int nonce;
|
private final int nonce;
|
||||||
private final Set<Peer> reportedPeers;
|
private final Set<Peer> reportedPeers;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<Integer> supportedCapabilities;
|
private final Capabilities supportedCapabilities;
|
||||||
|
|
||||||
public GetPeersRequest(NodeAddress senderNodeAddress, int nonce, Set<Peer> reportedPeers) {
|
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,
|
private GetPeersRequest(NodeAddress senderNodeAddress,
|
||||||
int nonce,
|
int nonce,
|
||||||
Set<Peer> reportedPeers,
|
Set<Peer> reportedPeers,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion) {
|
int messageVersion) {
|
||||||
super(messageVersion);
|
super(messageVersion);
|
||||||
checkNotNull(senderNodeAddress, "senderNodeAddress must not be null at GetPeersRequest");
|
checkNotNull(senderNodeAddress, "senderNodeAddress must not be null at GetPeersRequest");
|
||||||
|
@ -81,7 +80,7 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
|
||||||
.map(Peer::toProtoMessage)
|
.map(Peer::toProtoMessage)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
|
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder()
|
return getNetworkEnvelopeBuilder()
|
||||||
.setGetPeersRequest(builder)
|
.setGetPeersRequest(builder)
|
||||||
|
@ -94,7 +93,7 @@ public final class GetPeersRequest extends NetworkEnvelope implements PeerExchan
|
||||||
new HashSet<>(proto.getReportedPeersList().stream()
|
new HashSet<>(proto.getReportedPeersList().stream()
|
||||||
.map(Peer::fromProto)
|
.map(Peer::fromProto)
|
||||||
.collect(Collectors.toSet())),
|
.collect(Collectors.toSet())),
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion);
|
messageVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import bisq.common.proto.network.NetworkEnvelope;
|
||||||
import io.bisq.generated.protobuffer.PB;
|
import io.bisq.generated.protobuffer.PB;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -44,10 +43,10 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
|
||||||
private final int requestNonce;
|
private final int requestNonce;
|
||||||
private final Set<Peer> reportedPeers;
|
private final Set<Peer> reportedPeers;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<Integer> supportedCapabilities;
|
private final Capabilities supportedCapabilities;
|
||||||
|
|
||||||
public GetPeersResponse(int requestNonce, Set<Peer> reportedPeers) {
|
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,
|
private GetPeersResponse(int requestNonce,
|
||||||
Set<Peer> reportedPeers,
|
Set<Peer> reportedPeers,
|
||||||
@Nullable List<Integer> supportedCapabilities,
|
@Nullable Capabilities supportedCapabilities,
|
||||||
int messageVersion) {
|
int messageVersion) {
|
||||||
super(messageVersion);
|
super(messageVersion);
|
||||||
this.requestNonce = requestNonce;
|
this.requestNonce = requestNonce;
|
||||||
|
@ -73,7 +72,7 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
|
||||||
.map(Peer::toProtoMessage)
|
.map(Peer::toProtoMessage)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(supportedCapabilities));
|
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder()
|
return getNetworkEnvelopeBuilder()
|
||||||
.setGetPeersResponse(builder)
|
.setGetPeersResponse(builder)
|
||||||
|
@ -86,12 +85,12 @@ public final class GetPeersResponse extends NetworkEnvelope implements PeerExcha
|
||||||
.map(peer -> {
|
.map(peer -> {
|
||||||
NodeAddress nodeAddress = new NodeAddress(peer.getNodeAddress().getHostName(),
|
NodeAddress nodeAddress = new NodeAddress(peer.getNodeAddress().getHostName(),
|
||||||
peer.getNodeAddress().getPort());
|
peer.getNodeAddress().getPort());
|
||||||
return new Peer(nodeAddress, peer.getSupportedCapabilitiesList());
|
return new Peer(nodeAddress, Capabilities.fromIntList(peer.getSupportedCapabilitiesList()));
|
||||||
})
|
})
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
return new GetPeersResponse(proto.getRequestNonce(),
|
return new GetPeersResponse(proto.getRequestNonce(),
|
||||||
reportedPeers,
|
reportedPeers,
|
||||||
proto.getSupportedCapabilitiesList().isEmpty() ? null : proto.getSupportedCapabilitiesList(),
|
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||||
messageVersion);
|
messageVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,9 @@
|
||||||
|
|
||||||
package bisq.network.p2p.storage.payload;
|
package bisq.network.p2p.storage.payload;
|
||||||
|
|
||||||
|
import bisq.common.app.Capabilities;
|
||||||
import bisq.common.proto.network.NetworkPayload;
|
import bisq.common.proto.network.NetworkPayload;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for payloads which requires certain capability.
|
* Used for payloads which requires certain capability.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -31,5 +30,5 @@ public interface CapabilityRequiringPayload extends NetworkPayload {
|
||||||
/**
|
/**
|
||||||
* @return Capabilities the other node need to support to receive that message
|
* @return Capabilities the other node need to support to receive that message
|
||||||
*/
|
*/
|
||||||
List<Integer> getRequiredCapabilities();
|
Capabilities getRequiredCapabilities();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,13 @@ import bisq.core.app.misc.ModuleForAppWithP2p;
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
import bisq.common.app.AppModule;
|
import bisq.common.app.AppModule;
|
||||||
import bisq.common.app.Capabilities;
|
import bisq.common.app.Capabilities;
|
||||||
|
import bisq.common.app.Capability;
|
||||||
import bisq.common.setup.CommonSetup;
|
import bisq.common.setup.CommonSetup;
|
||||||
|
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -60,7 +63,10 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addCapabilities() {
|
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
|
@Override
|
||||||
|
|
Loading…
Add table
Reference in a new issue