mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 15:10:44 +01:00
Add semantic version model and test
This commit is contained in:
parent
8eaa7b5cd6
commit
603c3c512e
4 changed files with 130 additions and 130 deletions
|
@ -20,13 +20,44 @@ package io.bisq.common.app;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public class Version {
|
||||
private static final Logger log = LoggerFactory.getLogger(Version.class);
|
||||
|
||||
// The application versions
|
||||
// VERSION = 0.5.0.0 introduces proto buffer for the P2P network and local DB and is a not backward compatible update
|
||||
// VERSION = 0.5.0 introduces proto buffer for the P2P network and local DB and is a not backward compatible update
|
||||
// Therefore all sub versions start again with 1
|
||||
public static final String VERSION = "0.5.0.0";
|
||||
// We use semantic versioning with major, minor and patch
|
||||
public static final String VERSION = "0.5.0";
|
||||
|
||||
public static int getMajorVersion(String version) {
|
||||
return getSubVersion(version, 0);
|
||||
}
|
||||
|
||||
public static int getMinorVersion(String version) {
|
||||
return getSubVersion(version, 1);
|
||||
}
|
||||
|
||||
public static int getPatchVersion(String version) {
|
||||
return getSubVersion(version, 2);
|
||||
}
|
||||
|
||||
public static boolean isNewVersion(String newVersion) {
|
||||
return isNewVersion(newVersion, VERSION);
|
||||
}
|
||||
|
||||
static boolean isNewVersion(String newVersion, String currentVersion) {
|
||||
return getMajorVersion(newVersion) > getMajorVersion(currentVersion) ||
|
||||
getMinorVersion(newVersion) > getMinorVersion(currentVersion) ||
|
||||
getPatchVersion(newVersion) > getPatchVersion(currentVersion);
|
||||
}
|
||||
|
||||
static int getSubVersion(String version, int index) {
|
||||
final String[] split = version.split("\\.");
|
||||
checkArgument(split.length == 3, "Version number must be in semantic version format (contain 2 '.'). version=" + version);
|
||||
return Integer.parseInt(split[index]);
|
||||
}
|
||||
|
||||
// The version no. for the objects sent over the network. A change will break the serialization of old objects.
|
||||
// If objects are used for both network and database the network version is applied.
|
||||
|
|
47
common/src/test/java/io/bisq/common/app/VersionTest.java
Normal file
47
common/src/test/java/io/bisq/common/app/VersionTest.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.common.app;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class VersionTest {
|
||||
|
||||
@Test
|
||||
public void testVersionNumber() {
|
||||
assertEquals(0, Version.getMajorVersion("0.0.0"));
|
||||
assertEquals(1, Version.getMajorVersion("1.0.0"));
|
||||
|
||||
assertEquals(0, Version.getMinorVersion("0.0.0"));
|
||||
assertEquals(5, Version.getMinorVersion("0.5.0"));
|
||||
|
||||
assertEquals(0, Version.getPatchVersion("0.0.0"));
|
||||
assertEquals(5, Version.getPatchVersion("0.0.5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNewVersion() {
|
||||
assertFalse(Version.isNewVersion("0.0.0", "0.0.0"));
|
||||
assertTrue(Version.isNewVersion("1.0.0", "0.0.0"));
|
||||
assertTrue(Version.isNewVersion("0.1.0", "0.0.0"));
|
||||
assertTrue(Version.isNewVersion("0.0.1", "0.0.0"));
|
||||
assertTrue(Version.isNewVersion("0.5.1", "0.5.0"));
|
||||
assertFalse(Version.isNewVersion("0.5.0", "0.5.1"));
|
||||
}
|
||||
}
|
|
@ -17,10 +17,9 @@
|
|||
|
||||
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.common.crypto.Sig;
|
||||
import io.bisq.generated.protobuffer.PB;
|
||||
import io.bisq.network.p2p.storage.payload.StoragePayload;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@ -49,103 +48,56 @@ public final class Alert implements StoragePayload {
|
|||
@Nullable
|
||||
private String signatureAsBase64;
|
||||
@Nullable
|
||||
private PublicKey storagePublicKey;
|
||||
private byte[] ownerPubKeyBytes;
|
||||
@Nullable
|
||||
private final byte[] storagePublicKeyBytes;
|
||||
private PublicKey ownerPubKey;
|
||||
|
||||
// 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) {
|
||||
this.message = message;
|
||||
this.isUpdateInfo = isUpdateInfo;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PROTO BUFFER
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Alert(String message,
|
||||
boolean isUpdateInfo,
|
||||
String version,
|
||||
@Nullable byte[] storagePublicKeyBytes,
|
||||
@Nullable String signatureAsBase64,
|
||||
@Nullable Map<String, String> extraDataMap) {
|
||||
byte[] ownerPubKeyBytes,
|
||||
String signatureAsBase64,
|
||||
Map<String, String> extraDataMap) {
|
||||
this.message = message;
|
||||
this.isUpdateInfo = isUpdateInfo;
|
||||
this.version = version;
|
||||
this.storagePublicKeyBytes = storagePublicKeyBytes;
|
||||
this.ownerPubKeyBytes = ownerPubKeyBytes;
|
||||
this.signatureAsBase64 = signatureAsBase64;
|
||||
this.extraDataMap = extraDataMap;
|
||||
|
||||
ownerPubKey = Sig.getSigPublicKeyFromBytes(ownerPubKeyBytes);
|
||||
}
|
||||
|
||||
public Alert(String message,
|
||||
boolean isUpdateInfo,
|
||||
String version) {
|
||||
this(message, isUpdateInfo, version, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
public void setSigAndPubKey(String signatureAsBase64, PublicKey storagePublicKey) {
|
||||
this.signatureAsBase64 = signatureAsBase64;
|
||||
this.storagePublicKey = storagePublicKey;
|
||||
}
|
||||
|
||||
public boolean isNewVersion() {
|
||||
return isNewVersion(Version.VERSION);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected boolean isNewVersion(String myVersion) {
|
||||
// We need to support different version usages (0.5, 0.5.1, 0.5.1.1.1, 0.5.10.1)
|
||||
// So we fill up the right part up to 8 digits 0.5 -> 05000000, 0.5.1.1.1 -> 05111000
|
||||
// that should handle all cases.
|
||||
// TODO make it more elegant and add tests :-)
|
||||
|
||||
// In case the input comes in a corrupted format we don't want to screw up teh app
|
||||
try {
|
||||
String myVersionString = myVersion.replace(".", "");
|
||||
while (myVersionString.length() < 9)
|
||||
myVersionString += "0";
|
||||
int myVersionNum = Integer.valueOf(myVersionString);
|
||||
String alertVersionString = getVersion().replace(".", "");
|
||||
while (alertVersionString.length() < 9)
|
||||
alertVersionString += "0";
|
||||
int alertVersionNum = Integer.valueOf(alertVersionString);
|
||||
return myVersionNum < alertVersionNum;
|
||||
} catch (Throwable t) {
|
||||
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 toProtoMessage() {
|
||||
checkNotNull(getStoragePublicKeyBytes(), "storagePublicKeyBytes must not be null");
|
||||
checkNotNull(getSignatureAsBase64(), "signatureAsBase64 must not be null");
|
||||
checkNotNull(ownerPubKeyBytes, "storagePublicKeyBytes must not be null");
|
||||
checkNotNull(signatureAsBase64, "signatureAsBase64 must not be null");
|
||||
final PB.Alert.Builder builder = PB.Alert.newBuilder()
|
||||
.setMessage(getMessage())
|
||||
.setVersion(getVersion())
|
||||
.setIsUpdateInfo(isUpdateInfo())
|
||||
.setSignatureAsBase64(getSignatureAsBase64())
|
||||
.setStoragePublicKeyBytes(ByteString.copyFrom(getStoragePublicKeyBytes()));
|
||||
Optional.ofNullable(getExtraDataMap()).ifPresent(builder::putAllExtraDataMap);
|
||||
.setVersion(getVersion())
|
||||
.setOwnerPubKeyBytes(ByteString.copyFrom(ownerPubKeyBytes))
|
||||
.setSignatureAsBase64(getSignatureAsBase64());
|
||||
Optional.ofNullable(getExtraDataMap()).ifPresent(builder::putAllExtraData);
|
||||
return PB.StoragePayload.newBuilder().setAlert(builder).build();
|
||||
}
|
||||
|
||||
|
@ -153,9 +105,29 @@ public final class Alert implements StoragePayload {
|
|||
return new Alert(alert.getMessage(),
|
||||
alert.getIsUpdateInfo(),
|
||||
alert.getVersion(),
|
||||
alert.getStoragePublicKeyBytes().toByteArray(),
|
||||
alert.getOwnerPubKeyBytes().toByteArray(),
|
||||
alert.getSignatureAsBase64(),
|
||||
CollectionUtils.isEmpty(alert.getExtraDataMapMap()) ?
|
||||
null : alert.getExtraDataMapMap());
|
||||
CollectionUtils.isEmpty(alert.getExtraDataMap()) ?
|
||||
null : alert.getExtraDataMap());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setSigAndPubKey(String signatureAsBase64, PublicKey ownerPubKey) {
|
||||
this.signatureAsBase64 = signatureAsBase64;
|
||||
this.ownerPubKey = ownerPubKey;
|
||||
ownerPubKeyBytes = Sig.getSigPublicKeyBytes(ownerPubKey);
|
||||
}
|
||||
|
||||
public boolean isNewVersion() {
|
||||
return Version.isNewVersion(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTTL() {
|
||||
return TimeUnit.DAYS.toMillis(30);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +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 org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AlertTest {
|
||||
private static final Logger log = LoggerFactory.getLogger(AlertTest.class);
|
||||
|
||||
@Test
|
||||
public void testIsNewVersion() {
|
||||
Alert alert = new Alert(null, true, "0.4.9.9.1");
|
||||
assertTrue(alert.isNewVersion("0.4.9.9"));
|
||||
assertTrue(alert.isNewVersion("0.4.9.8"));
|
||||
assertTrue(alert.isNewVersion("0.4.9"));
|
||||
assertTrue(alert.isNewVersion("0.4.9.9.0"));
|
||||
assertFalse(alert.isNewVersion("0.4.9.9.1"));
|
||||
|
||||
alert = new Alert(null, true, "0.4.9.9.2");
|
||||
assertTrue(alert.isNewVersion("0.4.9.9.1"));
|
||||
assertFalse(alert.isNewVersion("0.4.9.9.2"));
|
||||
assertTrue(alert.isNewVersion("0.4.9.8"));
|
||||
assertTrue(alert.isNewVersion("0.4.9"));
|
||||
|
||||
alert = new Alert(null, true, "0.4.9.9");
|
||||
assertTrue(alert.isNewVersion("0.4.9"));
|
||||
assertTrue(alert.isNewVersion("0.4.9.8"));
|
||||
assertFalse(alert.isNewVersion("0.4.9.9"));
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue