diff --git a/common/src/main/java/io/bisq/common/app/DevEnv.java b/common/src/main/java/io/bisq/common/app/DevEnv.java index df46cf5dc2..a061225c1e 100644 --- a/common/src/main/java/io/bisq/common/app/DevEnv.java +++ b/common/src/main/java/io/bisq/common/app/DevEnv.java @@ -18,5 +18,5 @@ public class DevEnv { // If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and // offers are filled with default values. Intended to make dev testing faster. @SuppressWarnings("PointlessBooleanExpression") - public static final boolean DEV_MODE = STRESS_TEST_MODE || false; + public static final boolean DEV_MODE = STRESS_TEST_MODE || true; } diff --git a/common/src/main/java/io/bisq/common/crypto/PubKeyRing.java b/common/src/main/java/io/bisq/common/crypto/PubKeyRing.java index f261ce04fb..3e83ffe171 100644 --- a/common/src/main/java/io/bisq/common/crypto/PubKeyRing.java +++ b/common/src/main/java/io/bisq/common/crypto/PubKeyRing.java @@ -19,10 +19,8 @@ package io.bisq.common.crypto; import com.google.protobuf.ByteString; import io.bisq.common.Payload; -import io.bisq.common.app.Version; import io.bisq.generated.protobuffer.PB; import lombok.EqualsAndHashCode; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; @@ -31,7 +29,6 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.io.IOException; -import java.io.ObjectInputStream; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -46,70 +43,36 @@ import java.security.spec.X509EncodedKeySpec; @Slf4j @EqualsAndHashCode public final class PubKeyRing implements Payload { - // That object is sent over the wire, so we need to take care of version compatibility. - private static final long serialVersionUID = Version.P2P_NETWORK_VERSION; - - // Payload private final byte[] signaturePubKeyBytes; private final byte[] encryptionPubKeyBytes; private String pgpPubKeyAsPem; - // Domain - @Getter transient private PublicKey signaturePubKey; - @Getter transient private PublicKey encryptionPubKey; - @Getter + @Nullable // TODO remove Nullable once impl. transient private PGPPublicKey pgpPubKey; public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey, @Nullable PGPPublicKey pgpPubKey) { + this(new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded(), + new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded(), + PGP.getPEMFromPubKey(pgpPubKey)); + this.signaturePubKey = signaturePubKey; this.encryptionPubKey = encryptionPubKey; this.pgpPubKey = pgpPubKey; - - this.signaturePubKeyBytes = new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded(); - this.encryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded(); - - //TODO not impl yet - pgpPubKeyAsPem = PGP.getPEMFromPubKey(pgpPubKey); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes, @NotNull String pgpPubKeyAsPem) { this.signaturePubKeyBytes = signaturePubKeyBytes; this.encryptionPubKeyBytes = encryptionPubKeyBytes; this.pgpPubKeyAsPem = pgpPubKeyAsPem; - init(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - try { - in.defaultReadObject(); - init(); - } catch (Throwable t) { - log.warn("Cannot be deserialized." + t.getMessage()); - } - } - - private void init() { - try { - signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO, "BC") - .generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes)); - encryptionPubKey = KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO, "BC") - .generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes)); - - try { - this.pgpPubKey = PGP.getPubKeyFromPEM(pgpPubKeyAsPem); - } catch (IOException | PGPException e) { - log.error(e.toString()); - e.printStackTrace(); - throw new RuntimeException(e); - } - } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchProviderException e) { - e.printStackTrace(); - log.error(e.getMessage() + toString()); - } } @Override @@ -127,6 +90,50 @@ public final class PubKeyRing implements Payload { pubKeyRing.getPgpPubKeyAsPem()); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + + public PublicKey getSignaturePubKey() { + if (signaturePubKey == null) { + try { + signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO, "BC") + .generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes)); + } catch (InvalidKeySpecException | NoSuchProviderException | NoSuchAlgorithmException e) { + log.error("Key cannot be created. error={}, signaturePubKeyBytes.length={}", e.getMessage(), signaturePubKeyBytes.length); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + return signaturePubKey; + } + + public PublicKey getEncryptionPubKey() { + if (encryptionPubKey == null) { + try { + encryptionPubKey = KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO, "BC").generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes)); + } catch (InvalidKeySpecException | NoSuchProviderException | NoSuchAlgorithmException e) { + log.error("Key cannot be created. error={}, encryptionPubKeyBytes.length={}", e.getMessage(), encryptionPubKeyBytes.length); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + return encryptionPubKey; + } + + public PGPPublicKey getPgpPubKey() { + if (pgpPubKey == null) + try { + pgpPubKey = PGP.getPubKeyFromPEM(pgpPubKeyAsPem); + } catch (NoSuchAlgorithmException | PGPException | IOException | InvalidKeySpecException e) { + log.error("Key cannot be created. error={}, pgpPubKeyAsPem={}", e.getMessage(), pgpPubKeyAsPem); + e.printStackTrace(); + //throw new RuntimeException(e); + } + return pgpPubKey; + } + // Hex @Override public String toString() { diff --git a/core/src/main/java/io/bisq/core/trade/statistics/TradeStatistics.java b/core/src/main/java/io/bisq/core/trade/statistics/TradeStatistics.java index f0460dc75a..cd10926e02 100644 --- a/core/src/main/java/io/bisq/core/trade/statistics/TradeStatistics.java +++ b/core/src/main/java/io/bisq/core/trade/statistics/TradeStatistics.java @@ -1,6 +1,5 @@ package io.bisq.core.trade.statistics; -import io.bisq.common.app.Version; import io.bisq.common.crypto.PubKeyRing; import io.bisq.common.locale.CurrencyUtil; import io.bisq.common.monetary.Altcoin; @@ -32,8 +31,6 @@ import java.util.concurrent.TimeUnit; @Slf4j @Immutable public final class TradeStatistics implements LazyProcessedStoragePayload, /*CapabilityRequiringPayload,*/ PersistedStoragePayload { - @JsonExclude - private static final long serialVersionUID = Version.P2P_NETWORK_VERSION; @JsonExclude public static final long TTL = TimeUnit.DAYS.toMillis(30); @@ -87,8 +84,12 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap null); } - // Called from PB - public TradeStatistics(OfferPayload.Direction direction, + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + private TradeStatistics(OfferPayload.Direction direction, String baseCurrency, String counterCurrency, String offerPaymentMethod, @@ -122,6 +123,54 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap this.extraDataMap = extraDataMap; } + @Override + public PB.StoragePayload toProto() { + final PB.TradeStatistics.Builder builder = PB.TradeStatistics.newBuilder() + .setBaseCurrency(baseCurrency) + .setCounterCurrency(counterCurrency) + .setDirection(PB.OfferPayload.Direction.valueOf(direction.name())) + .setTradePrice(tradePrice) + .setTradeAmount(tradeAmount) + .setTradeDate(tradeDate) + .setPaymentMethodId(paymentMethodId) + .setOfferDate(offerDate) + .setUseMarketBasedPrice(useMarketBasedPrice) + .setMarketPriceMargin(marketPriceMargin) + .setOfferAmount(offerAmount) + .setOfferMinAmount(offerMinAmount) + .setOfferId(offerId) + .setDepositTxId(depositTxId) + .setPubKeyRing(pubKeyRing.toProto()); + Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraDataMap); + return PB.StoragePayload.newBuilder().setTradeStatistics(builder).build(); + } + + public static TradeStatistics fromProto(PB.TradeStatistics tradeStatistics) { + return new TradeStatistics( + OfferPayload.Direction.fromProto(tradeStatistics.getDirection()), + tradeStatistics.getBaseCurrency(), + tradeStatistics.getCounterCurrency(), + tradeStatistics.getPaymentMethodId(), + tradeStatistics.getOfferDate(), + tradeStatistics.getUseMarketBasedPrice(), + tradeStatistics.getMarketPriceMargin(), + tradeStatistics.getOfferAmount(), + tradeStatistics.getOfferMinAmount(), + tradeStatistics.getOfferId(), + tradeStatistics.getTradePrice(), + tradeStatistics.getTradeAmount(), + tradeStatistics.getTradeDate(), + tradeStatistics.getDepositTxId(), + PubKeyRing.fromProto(tradeStatistics.getPubKeyRing()), + CollectionUtils.isEmpty(tradeStatistics.getExtraDataMapMap()) ? + null : tradeStatistics.getExtraDataMapMap()); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + @Override public long getTTL() { return TTL; @@ -163,50 +212,6 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap return new Volume(new ExchangeRate((Fiat) getTradePrice().getMonetary()).coinToFiat(getTradeAmount())); } - @Override - public PB.StoragePayload toProto() { - final PB.TradeStatistics.Builder builder = PB.TradeStatistics.newBuilder() - .setBaseCurrency(baseCurrency) - .setCounterCurrency(counterCurrency) - .setDirection(PB.OfferPayload.Direction.valueOf(direction.name())) - .setTradePrice(tradePrice) - .setTradeAmount(tradeAmount) - .setTradeDate(tradeDate) - .setPaymentMethodId(paymentMethodId) - .setOfferDate(offerDate) - .setUseMarketBasedPrice(useMarketBasedPrice) - .setMarketPriceMargin(marketPriceMargin) - .setOfferAmount(offerAmount) - .setOfferMinAmount(offerMinAmount) - .setOfferId(offerId) - .setDepositTxId(depositTxId) - .setPubKeyRing(pubKeyRing.toProto()); - Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraDataMap); - return PB.StoragePayload.newBuilder().setTradeStatistics(builder).build(); - } - - public static TradeStatistics fromProto(PB.TradeStatistics tradeStatistics) { - return new TradeStatistics(OfferPayload.Direction.fromProto(tradeStatistics.getDirection()), - tradeStatistics.getBaseCurrency(), - tradeStatistics.getCounterCurrency(), - tradeStatistics.getPaymentMethodId(), - tradeStatistics.getOfferDate(), - tradeStatistics.getUseMarketBasedPrice(), - tradeStatistics.getMarketPriceMargin(), - tradeStatistics.getOfferAmount(), - tradeStatistics.getOfferMinAmount(), - tradeStatistics.getOfferId(), - tradeStatistics.getTradePrice(), - tradeStatistics.getTradeAmount(), - tradeStatistics.getTradeDate(), - tradeStatistics.getDepositTxId(), - new PubKeyRing(tradeStatistics.getPubKeyRing().getSignaturePubKeyBytes().toByteArray(), - tradeStatistics.getPubKeyRing().getEncryptionPubKeyBytes().toByteArray(), - tradeStatistics.getPubKeyRing().getPgpPubKeyAsPem()), - CollectionUtils.isEmpty(tradeStatistics.getExtraDataMapMap()) ? - null : tradeStatistics.getExtraDataMapMap()); - } - // We don't include the pubKeyRing as both traders might publish it if the maker uses an old // version and update later (taker publishes first, then later maker) // We also don't include the trade date as that is set locally and different for maker and taker