Remove Alert delegates

This commit is contained in:
Manfred Karrer 2017-03-27 23:16:23 -05:00
parent 22287a25e0
commit 1215834864
10 changed files with 104 additions and 265 deletions

View file

@ -17,11 +17,6 @@
<artifactId>common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.bisq</groupId>
<artifactId>vo</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.bisq</groupId>
<artifactId>network</artifactId>

View file

@ -18,44 +18,76 @@
package io.bisq.core.alert;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ByteString;
import io.bisq.common.app.Version;
import io.bisq.common.crypto.CryptoUtils;
import io.bisq.generated.protobuffer.PB;
import io.bisq.network.p2p.storage.payload.StoragePayload;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
@EqualsAndHashCode
@Getter
@ToString
@Slf4j
public final class Alert {
public final class Alert implements StoragePayload {
//TODO remove after refact.
private static final long serialVersionUID = 1;
@Delegate
@Getter
private AlertVO alertVO;
private final String message;
private final String version;
private final boolean isUpdateInfo;
@Nullable
private String signatureAsBase64;
@Nullable
private PublicKey storagePublicKey;
@Nullable
private final byte[] storagePublicKeyBytes;
// Should be only used in emergency case if we need to add data but do not want to break backward compatibility
// at the P2P network storage checks. The hash of the object will be used to verify if the data is valid. Any new
// field in a class would break that hash and therefore break the storage mechanism.
@Nullable
private Map<String, String> extraDataMap;
// StoragePayload
private transient PublicKey ownerPubKey;
public Alert(String message,
boolean isUpdateInfo,
String version,
@Nullable byte[] storagePublicKeyBytes,
@Nullable String signatureAsBase64,
@Nullable Map<String, String> extraDataMap) {
this.message = message;
this.isUpdateInfo = isUpdateInfo;
this.version = version;
this.storagePublicKeyBytes = storagePublicKeyBytes;
this.signatureAsBase64 = signatureAsBase64;
this.extraDataMap = extraDataMap;
}
public Alert(String message,
boolean isUpdateInfo,
String version) {
//TODO builder pattern might be better
// Or refactor client code so it is not using a half baked object
this.alertVO = new AlertVO(message, isUpdateInfo, version, null, null, null);
this(message, isUpdateInfo, version, null, null, null);
}
public Alert(AlertVO alertVO) {
this.alertVO = alertVO;
}
public void setSigAndPubKey(String signatureAsBase64, PublicKey storagePublicKey) {
this.alertVO = new AlertVO(alertVO.getMessage(),
alertVO.isUpdateInfo(),
alertVO.getVersion(),
new X509EncodedKeySpec(storagePublicKey.getEncoded()).getEncoded(),
signatureAsBase64,
alertVO.getExtraDataMap());
this.signatureAsBase64 = signatureAsBase64;
this.storagePublicKey = storagePublicKey;
}
public boolean isNewVersion() {
@ -75,7 +107,7 @@ public final class Alert {
while (myVersionString.length() < 9)
myVersionString += "0";
int myVersionNum = Integer.valueOf(myVersionString);
String alertVersionString = alertVO.getVersion().replace(".", "");
String alertVersionString = getVersion().replace(".", "");
while (alertVersionString.length() < 9)
alertVersionString += "0";
int alertVersionNum = Integer.valueOf(alertVersionString);
@ -84,4 +116,38 @@ public final class Alert {
return false;
}
}
//StoragePayload
@Override
public long getTTL() {
return TimeUnit.DAYS.toMillis(30);
}
@Override
public PublicKey getOwnerPubKey() {
try {
checkNotNull(getStoragePublicKeyBytes(), "alertVO.getStoragePublicKeyBytes() must not be null");
if (ownerPubKey == null)
ownerPubKey = CryptoUtils.getPubKeyFromBytes(getStoragePublicKeyBytes());
return ownerPubKey;
} catch (Throwable t) {
log.error(t.toString());
return null;
}
}
//Marshaller
@Override
public PB.StoragePayload toProto() {
checkNotNull(getStoragePublicKeyBytes(), "storagePublicKeyBytes must not be null");
checkNotNull(getSignatureAsBase64(), "signatureAsBase64 must not be null");
final PB.AlertProto.Builder builder = PB.AlertProto.newBuilder()
.setMessage(getMessage())
.setVersion(getVersion())
.setIsUpdateInfo(isUpdateInfo())
.setSignatureAsBase64(getSignatureAsBase64())
.setStoragePublicKeyBytes(ByteString.copyFrom(getStoragePublicKeyBytes()));
Optional.ofNullable(getExtraDataMap()).ifPresent(builder::putAllExtraDataMap);
return PB.StoragePayload.newBuilder().setAlertProto(builder).build();
}
}

View file

@ -70,8 +70,8 @@ public class AlertManager {
@Override
public void onAdded(ProtectedStorageEntry data) {
final StoragePayload storagePayload = data.getStoragePayload();
if (storagePayload instanceof AlertPayload) {
Alert alert = new Alert(((AlertPayload) storagePayload).getAlertVO());
if (storagePayload instanceof Alert) {
Alert alert = (Alert) storagePayload;
if (verifySignature(alert))
alertMessageProperty.set(alert);
}
@ -80,9 +80,8 @@ public class AlertManager {
@Override
public void onRemoved(ProtectedStorageEntry data) {
final StoragePayload storagePayload = data.getStoragePayload();
if (storagePayload instanceof AlertPayload) {
Alert alert = new Alert(((AlertPayload) storagePayload).getAlertVO());
if (verifySignature(alert))
if (storagePayload instanceof Alert) {
if (verifySignature((Alert) storagePayload))
alertMessageProperty.set(null);
}
}
@ -108,7 +107,7 @@ public class AlertManager {
if (isKeyValid) {
signAndAddSignatureToAlertMessage(alert);
user.setDevelopersAlert(alert);
boolean result = p2PService.addData(new AlertPayload(alert.getAlertVO()), true);
boolean result = p2PService.addData(alert, true);
if (result) {
log.trace("Add alertMessage to network was successful. AlertMessage = " + alert);
}
@ -120,7 +119,7 @@ public class AlertManager {
public boolean removeAlertMessageIfKeyIsValid(String privKeyString) {
Alert alert = user.getDevelopersAlert();
if (isKeyValid(privKeyString) && alert != null) {
if (p2PService.removeData(new AlertPayload(alert.getAlertVO()), true))
if (p2PService.removeData(alert, true))
log.trace("Remove alertMessage from network was successful. AlertMessage = " + alert);
user.setDevelopersAlert(null);

View file

@ -1,58 +0,0 @@
/*
* 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 io.bisq.core.alert;
import io.bisq.common.crypto.CryptoUtils;
import io.bisq.network.p2p.storage.payload.StoragePayload;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.concurrent.Immutable;
import java.security.PublicKey;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
@Immutable
public final class AlertPayload extends AlertProto implements StoragePayload {
// lazy set
private transient PublicKey ownerPubKey;
public AlertPayload(AlertVO alertVO) {
super(alertVO);
}
@Override
public long getTTL() {
return TimeUnit.DAYS.toMillis(30);
}
@Override
public PublicKey getOwnerPubKey() {
try {
checkNotNull(getStoragePublicKeyBytes(), "alertVO.getStoragePublicKeyBytes() must not be null");
if (ownerPubKey == null)
ownerPubKey = CryptoUtils.getPubKeyFromBytes(getStoragePublicKeyBytes());
return ownerPubKey;
} catch (Throwable t) {
log.error(t.toString());
return null;
}
}
}

View file

@ -1,29 +0,0 @@
/*
* 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 io.bisq.core.alert;
import io.bisq.core.PersistableNew;
import javax.annotation.concurrent.Immutable;
@Immutable
public final class AlertPersistable extends AlertProto implements PersistableNew {
public AlertPersistable(AlertVO alertVO) {
super(alertVO);
}
}

View file

@ -1,56 +0,0 @@
/*
* 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 io.bisq.core.alert;
import com.google.protobuf.ByteString;
import io.bisq.common.Marshaller;
import io.bisq.generated.protobuffer.PB;
import lombok.Getter;
import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.concurrent.Immutable;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
@Immutable
public abstract class AlertProto implements Marshaller {
@Delegate
@Getter
private final AlertVO alertVO;
public AlertProto(AlertVO alertVO) {
this.alertVO = alertVO;
}
@Override
public PB.StoragePayload toProto() {
checkNotNull(alertVO.getStoragePublicKeyBytes(), "storagePublicKeyBytes must not be null");
checkNotNull(alertVO.getSignatureAsBase64(), "signatureAsBase64 must not be null");
final PB.AlertProto.Builder builder = PB.AlertProto.newBuilder()
.setMessage(alertVO.getMessage())
.setVersion(alertVO.getVersion())
.setIsUpdateInfo(alertVO.isUpdateInfo())
.setSignatureAsBase64(alertVO.getSignatureAsBase64())
.setStoragePublicKeyBytes(ByteString.copyFrom(alertVO.getStoragePublicKeyBytes()));
Optional.ofNullable(alertVO.getExtraDataMap()).ifPresent(builder::putAllExtraDataMap);
return PB.StoragePayload.newBuilder().setAlertProto(builder).build();
}
}

View file

@ -1,58 +0,0 @@
/*
* 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 io.bisq.core.alert;
import lombok.Value;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.util.Map;
@Value
@Immutable
public final class AlertVO {
//TODO remove after refact.
private static final long serialVersionUID = 1;
private final String message;
private final String version;
private final boolean isUpdateInfo;
@Nullable
private final String signatureAsBase64;
@Nullable
private final byte[] storagePublicKeyBytes;
// Should be only used in emergency case if we need to add data but do not want to break backward compatibility
// at the P2P network storage checks. The hash of the object will be used to verify if the data is valid. Any new
// field in a class would break that hash and therefore break the storage mechanism.
@Nullable
private Map<String, String> extraDataMap;
public AlertVO(String message,
boolean isUpdateInfo,
String version,
@Nullable byte[] storagePublicKeyBytes,
@Nullable String signatureAsBase64,
@Nullable Map<String, String> extraDataMap) {
this.message = message;
this.isUpdateInfo = isUpdateInfo;
this.version = version;
this.storagePublicKeyBytes = storagePublicKeyBytes;
this.signatureAsBase64 = signatureAsBase64;
this.extraDataMap = extraDataMap;
}
}

View file

@ -6,8 +6,7 @@ import io.bisq.common.crypto.SealedAndSigned;
import io.bisq.common.locale.CountryUtil;
import io.bisq.common.locale.CurrencyUtil;
import io.bisq.common.monetary.Price;
import io.bisq.core.alert.AlertPayload;
import io.bisq.core.alert.AlertVO;
import io.bisq.core.alert.Alert;
import io.bisq.core.alert.PrivateNotificationMessage;
import io.bisq.core.alert.PrivateNotificationPayload;
import io.bisq.core.arbitration.*;
@ -605,12 +604,12 @@ public class CoreProtobufferResolver implements ProtobufferResolver {
PB.AlertProto protoAlert = protoEntry.getAlertProto();
extraDataMapMap = CollectionUtils.isEmpty(protoAlert.getExtraDataMapMap()) ?
null : protoAlert.getExtraDataMapMap();
storagePayload = new AlertPayload(new AlertVO(protoAlert.getMessage(),
storagePayload = new Alert(protoAlert.getMessage(),
protoAlert.getIsUpdateInfo(),
protoAlert.getVersion(),
protoAlert.getStoragePublicKeyBytes().toByteArray(),
protoAlert.getSignatureAsBase64(),
extraDataMapMap));
extraDataMapMap);
break;
case ARBITRATOR:
PB.Arbitrator arbitrator = protoEntry.getArbitrator();

View file

@ -24,7 +24,6 @@ import io.bisq.common.locale.TradeCurrency;
import io.bisq.common.persistance.Persistable;
import io.bisq.common.storage.Storage;
import io.bisq.core.alert.Alert;
import io.bisq.core.alert.AlertPersistable;
import io.bisq.core.arbitration.Arbitrator;
import io.bisq.core.arbitration.Mediator;
import io.bisq.core.filter.Filter;
@ -67,9 +66,9 @@ public final class User implements Persistable {
private PaymentAccount currentPaymentAccount;
private List<String> acceptedLanguageLocaleCodes = new ArrayList<>();
@Nullable
private AlertPersistable developersPersistableAlert;
private Alert developersAlert;
@Nullable
private AlertPersistable displayedPersistableAlert;
private Alert displayedAlert;
@Nullable
private Filter developersFilter;
@ -112,8 +111,8 @@ public final class User implements Persistable {
registeredArbitrator = persisted.getRegisteredArbitrator();
registeredMediator = persisted.getRegisteredMediator();
developersPersistableAlert = persisted.getDevelopersPersistableAlert();
displayedPersistableAlert = persisted.getDisplayedPersistableAlert();
developersAlert = persisted.getDevelopersAlert();
displayedAlert = persisted.getDisplayedAlert();
developersFilter = persisted.getDevelopersFilter();
} else {
accountID = String.valueOf(Math.abs(keyRing.getPubKeyRing().hashCode()));
@ -385,39 +384,23 @@ public final class User implements Persistable {
return findFirstPaymentAccountWithCurrency(tradeCurrency) != null;
}
public void setDevelopersAlert(@Nullable Alert alert) {
if (alert != null)
this.developersPersistableAlert = new AlertPersistable(alert.getAlertVO());
else
this.developersPersistableAlert = null;
public void setDevelopersAlert(@Nullable Alert developersAlert) {
this.developersAlert = developersAlert;
storage.queueUpForSave();
}
@Nullable
public Alert getDevelopersAlert() {
return developersPersistableAlert != null ? new Alert(developersPersistableAlert.getAlertVO()) : null;
return developersAlert;
}
public void setDisplayedAlert(@Nullable Alert alert) {
if (alert != null)
this.displayedPersistableAlert = new AlertPersistable(alert.getAlertVO());
else
this.displayedPersistableAlert = null;
public void setDisplayedAlert(@Nullable Alert displayedAlert) {
this.displayedAlert = displayedAlert;
storage.queueUpForSave();
}
@Nullable
public Alert getDisplayedAlert() {
return displayedPersistableAlert != null ? new Alert(displayedPersistableAlert.getAlertVO()) : null;
}
@Nullable
private AlertPersistable getDevelopersPersistableAlert() {
return developersPersistableAlert;
}
@Nullable
private AlertPersistable getDisplayedPersistableAlert() {
return displayedPersistableAlert;
return displayedAlert;
}
}

View file

@ -40,8 +40,6 @@
<modules>
<module>common</module>
<module>vo</module>
<module>protobuffer</module>
<module>network</module>
<module>core</module>
<module>jsocks</module>