mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 15:10:44 +01:00
Add support for TTL defined by payload message so we can use
different TTL for lower prio mailbox messages like AckMessages. As we cannot add a field without breaking signatures we need to use the extraMap in MailboxStoragePayload
This commit is contained in:
parent
7a2501ea1b
commit
35ef3b842f
11 changed files with 65 additions and 18 deletions
|
@ -47,6 +47,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ToString
|
@ToString
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class Alert implements ProtectedStoragePayload, ExpirablePayload {
|
public final class Alert implements ProtectedStoragePayload, ExpirablePayload {
|
||||||
|
public static final long TTL = TimeUnit.DAYS.toMillis(90);
|
||||||
|
|
||||||
private final String message;
|
private final String message;
|
||||||
private final boolean isUpdateInfo;
|
private final boolean isUpdateInfo;
|
||||||
private final String version;
|
private final String version;
|
||||||
|
@ -131,7 +133,7 @@ public final class Alert implements ProtectedStoragePayload, ExpirablePayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
return TimeUnit.DAYS.toMillis(90);
|
return TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSigAndPubKey(String signatureAsBase64, PublicKey ownerPubKey) {
|
public void setSigAndPubKey(String signatureAsBase64, PublicKey ownerPubKey) {
|
||||||
|
|
|
@ -56,6 +56,9 @@ import javax.annotation.concurrent.Immutable;
|
||||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
public class TempProposalPayload implements ProcessOncePersistableNetworkPayload, ProtectedStoragePayload,
|
public class TempProposalPayload implements ProcessOncePersistableNetworkPayload, ProtectedStoragePayload,
|
||||||
ExpirablePayload, PersistablePayload {
|
ExpirablePayload, PersistablePayload {
|
||||||
|
// We keep data 2 months to be safe if we increase durations of cycle. Also give a bit more resilience in case
|
||||||
|
// of any issues with the append-only data store
|
||||||
|
public static final long TTL = TimeUnit.DAYS.toMillis(60);
|
||||||
|
|
||||||
protected final Proposal proposal;
|
protected final Proposal proposal;
|
||||||
protected final byte[] ownerPubKeyEncoded;
|
protected final byte[] ownerPubKeyEncoded;
|
||||||
|
@ -124,8 +127,6 @@ public class TempProposalPayload implements ProcessOncePersistableNetworkPayload
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
// We keep data 2 months to be safe if we increase durations of cycle. Also give a bit more resilience in case
|
return TTL;
|
||||||
// of any issues with the append-only data store
|
|
||||||
return TimeUnit.DAYS.toMillis(60);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ import javax.annotation.Nullable;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Value
|
@Value
|
||||||
public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||||
|
public static final long TTL = TimeUnit.DAYS.toMillis(180);
|
||||||
|
|
||||||
private final List<String> bannedOfferIds;
|
private final List<String> bannedOfferIds;
|
||||||
private final List<String> nodeAddressesBannedFromTrading;
|
private final List<String> nodeAddressesBannedFromTrading;
|
||||||
private final List<String> bannedAutoConfExplorers;
|
private final List<String> bannedAutoConfExplorers;
|
||||||
|
@ -361,7 +363,7 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
return TimeUnit.DAYS.toMillis(180);
|
return TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -55,6 +55,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@Getter
|
@Getter
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class OfferPayload implements ProtectedStoragePayload, ExpirablePayload, RequiresOwnerIsOnlinePayload {
|
public final class OfferPayload implements ProtectedStoragePayload, ExpirablePayload, RequiresOwnerIsOnlinePayload {
|
||||||
|
public static final long TTL = TimeUnit.MINUTES.toMillis(9);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Enum
|
// Enum
|
||||||
|
@ -373,7 +374,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
return TimeUnit.MINUTES.toMillis(9);
|
return TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -43,8 +43,8 @@ import javax.annotation.Nullable;
|
||||||
@EqualsAndHashCode(callSuper = true, exclude = {"uid"})
|
@EqualsAndHashCode(callSuper = true, exclude = {"uid"})
|
||||||
@Value
|
@Value
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class AckMessage extends NetworkEnvelope implements MailboxMessage, PersistablePayload,
|
public final class AckMessage extends NetworkEnvelope implements MailboxMessage, PersistablePayload, ExpirablePayload {
|
||||||
ExpirablePayload {
|
public static final long TTL = TimeUnit.DAYS.toMillis(7);
|
||||||
|
|
||||||
private final String uid;
|
private final String uid;
|
||||||
private final NodeAddress senderNodeAddress;
|
private final NodeAddress senderNodeAddress;
|
||||||
|
@ -150,10 +150,9 @@ public final class AckMessage extends NetworkEnvelope implements MailboxMessage,
|
||||||
// API
|
// API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//TODO has no effect, see comment at class definition
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
return TimeUnit.DAYS.toMillis(10);
|
return TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -44,8 +44,7 @@ public final class PrefixedSealedAndSignedMessage extends NetworkEnvelope implem
|
||||||
|
|
||||||
private final String uid;
|
private final String uid;
|
||||||
|
|
||||||
public PrefixedSealedAndSignedMessage(NodeAddress senderNodeAddress,
|
public PrefixedSealedAndSignedMessage(NodeAddress senderNodeAddress, SealedAndSigned sealedAndSigned) {
|
||||||
SealedAndSigned sealedAndSigned) {
|
|
||||||
this(senderNodeAddress,
|
this(senderNodeAddress,
|
||||||
sealedAndSigned,
|
sealedAndSigned,
|
||||||
new byte[0],
|
new byte[0],
|
||||||
|
|
|
@ -35,6 +35,7 @@ import bisq.network.p2p.seed.SeedNodeRepository;
|
||||||
import bisq.network.p2p.storage.HashMapChangedListener;
|
import bisq.network.p2p.storage.HashMapChangedListener;
|
||||||
import bisq.network.p2p.storage.P2PDataStorage;
|
import bisq.network.p2p.storage.P2PDataStorage;
|
||||||
import bisq.network.p2p.storage.messages.AddDataMessage;
|
import bisq.network.p2p.storage.messages.AddDataMessage;
|
||||||
|
import bisq.network.p2p.storage.payload.ExpirablePayload;
|
||||||
import bisq.network.p2p.storage.payload.MailboxStoragePayload;
|
import bisq.network.p2p.storage.payload.MailboxStoragePayload;
|
||||||
import bisq.network.p2p.storage.payload.ProtectedMailboxStorageEntry;
|
import bisq.network.p2p.storage.payload.ProtectedMailboxStorageEntry;
|
||||||
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
|
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
|
||||||
|
@ -213,9 +214,21 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
PublicKey receiverStoragePublicKey = peersPubKeyRing.getSignaturePubKey();
|
PublicKey receiverStoragePublicKey = peersPubKeyRing.getSignaturePubKey();
|
||||||
|
|
||||||
|
long ttl;
|
||||||
|
if (message instanceof ExpirablePayload) {
|
||||||
|
ttl = ((ExpirablePayload) message).getTTL();
|
||||||
|
log.trace("We take TTL from {}. ttl={}", message.getClass().getSimpleName(), ttl);
|
||||||
|
} else {
|
||||||
|
ttl = MailboxStoragePayload.TTL;
|
||||||
|
log.trace("Message is not of type ExpirablePayload. " +
|
||||||
|
"We use the default TTL from MailboxStoragePayload. ttl={}; message={}",
|
||||||
|
ttl, message.getClass().getSimpleName());
|
||||||
|
}
|
||||||
addMailboxData(new MailboxStoragePayload(prefixedSealedAndSignedMessage,
|
addMailboxData(new MailboxStoragePayload(prefixedSealedAndSignedMessage,
|
||||||
keyRing.getSignatureKeyPair().getPublic(),
|
keyRing.getSignatureKeyPair().getPublic(),
|
||||||
receiverStoragePublicKey),
|
receiverStoragePublicKey,
|
||||||
|
ttl),
|
||||||
receiverStoragePublicKey,
|
receiverStoragePublicKey,
|
||||||
sendMailboxMessageListener);
|
sendMailboxMessageListener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
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;
|
||||||
|
@ -55,6 +56,9 @@ import javax.annotation.Nullable;
|
||||||
public final class MailboxStoragePayload implements ProtectedStoragePayload, ExpirablePayload, AddOncePayload {
|
public final class MailboxStoragePayload implements ProtectedStoragePayload, ExpirablePayload, AddOncePayload {
|
||||||
public static final long TTL = TimeUnit.DAYS.toMillis(15);
|
public static final long TTL = TimeUnit.DAYS.toMillis(15);
|
||||||
|
|
||||||
|
// Added in 1.5.5
|
||||||
|
public static final String EXTRA_MAP_KEY_TTL = "ttl";
|
||||||
|
|
||||||
private final PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage;
|
private final PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage;
|
||||||
private PublicKey senderPubKeyForAddOperation;
|
private PublicKey senderPubKeyForAddOperation;
|
||||||
private final byte[] senderPubKeyForAddOperationBytes;
|
private final byte[] senderPubKeyForAddOperationBytes;
|
||||||
|
@ -63,18 +67,27 @@ public final class MailboxStoragePayload implements ProtectedStoragePayload, Exp
|
||||||
// Should be only used in emergency case if we need to add data but do not want to break backward compatibility
|
// 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
|
// 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.
|
// field in a class would break that hash and therefore break the storage mechanism.
|
||||||
|
|
||||||
|
// We add optional TTL entry in v 1.5.5 so we can support different TTL for trade messages and for AckMessages
|
||||||
@Nullable
|
@Nullable
|
||||||
private Map<String, String> extraDataMap;
|
private Map<String, String> extraDataMap;
|
||||||
|
|
||||||
public MailboxStoragePayload(PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage,
|
public MailboxStoragePayload(PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage,
|
||||||
@NotNull PublicKey senderPubKeyForAddOperation,
|
@NotNull PublicKey senderPubKeyForAddOperation,
|
||||||
PublicKey ownerPubKey) {
|
PublicKey ownerPubKey,
|
||||||
|
long ttl) {
|
||||||
this.prefixedSealedAndSignedMessage = prefixedSealedAndSignedMessage;
|
this.prefixedSealedAndSignedMessage = prefixedSealedAndSignedMessage;
|
||||||
this.senderPubKeyForAddOperation = senderPubKeyForAddOperation;
|
this.senderPubKeyForAddOperation = senderPubKeyForAddOperation;
|
||||||
this.ownerPubKey = ownerPubKey;
|
this.ownerPubKey = ownerPubKey;
|
||||||
|
|
||||||
senderPubKeyForAddOperationBytes = Sig.getPublicKeyBytes(senderPubKeyForAddOperation);
|
senderPubKeyForAddOperationBytes = Sig.getPublicKeyBytes(senderPubKeyForAddOperation);
|
||||||
ownerPubKeyBytes = Sig.getPublicKeyBytes(ownerPubKey);
|
ownerPubKeyBytes = Sig.getPublicKeyBytes(ownerPubKey);
|
||||||
|
|
||||||
|
// We do not permit longer TTL as the default one
|
||||||
|
if (ttl < TTL) {
|
||||||
|
extraDataMap = new HashMap<>();
|
||||||
|
extraDataMap.put(EXTRA_MAP_KEY_TTL, String.valueOf(ttl));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,6 +133,16 @@ public final class MailboxStoragePayload implements ProtectedStoragePayload, Exp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTTL() {
|
public long getTTL() {
|
||||||
|
if (extraDataMap != null && extraDataMap.containsKey(EXTRA_MAP_KEY_TTL)) {
|
||||||
|
try {
|
||||||
|
long ttl = Long.parseLong(extraDataMap.get(EXTRA_MAP_KEY_TTL));
|
||||||
|
if (ttl < TTL) {
|
||||||
|
return ttl;
|
||||||
|
}
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If not set in extraDataMap or value is invalid or too large we return default TTL
|
||||||
return TTL;
|
return TTL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class AddDataMessageTest {
|
||||||
SealedAndSigned sealedAndSigned = new SealedAndSigned(RandomUtils.nextBytes(10), RandomUtils.nextBytes(10), RandomUtils.nextBytes(10), keyRing1.getPubKeyRing().getSignaturePubKey());
|
SealedAndSigned sealedAndSigned = new SealedAndSigned(RandomUtils.nextBytes(10), RandomUtils.nextBytes(10), RandomUtils.nextBytes(10), keyRing1.getPubKeyRing().getSignaturePubKey());
|
||||||
PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage = new PrefixedSealedAndSignedMessage(new NodeAddress("host", 1000), sealedAndSigned);
|
PrefixedSealedAndSignedMessage prefixedSealedAndSignedMessage = new PrefixedSealedAndSignedMessage(new NodeAddress("host", 1000), sealedAndSigned);
|
||||||
MailboxStoragePayload mailboxStoragePayload = new MailboxStoragePayload(prefixedSealedAndSignedMessage,
|
MailboxStoragePayload mailboxStoragePayload = new MailboxStoragePayload(prefixedSealedAndSignedMessage,
|
||||||
keyRing1.getPubKeyRing().getSignaturePubKey(), keyRing1.getPubKeyRing().getSignaturePubKey());
|
keyRing1.getPubKeyRing().getSignaturePubKey(), keyRing1.getPubKeyRing().getSignaturePubKey(), MailboxStoragePayload.TTL);
|
||||||
ProtectedStorageEntry protectedStorageEntry = new ProtectedMailboxStorageEntry(mailboxStoragePayload,
|
ProtectedStorageEntry protectedStorageEntry = new ProtectedMailboxStorageEntry(mailboxStoragePayload,
|
||||||
keyRing1.getSignatureKeyPair().getPublic(), 1, RandomUtils.nextBytes(10), keyRing1.getPubKeyRing().getSignaturePubKey(), Clock.systemDefaultZone());
|
keyRing1.getSignatureKeyPair().getPublic(), 1, RandomUtils.nextBytes(10), keyRing1.getPubKeyRing().getSignaturePubKey(), Clock.systemDefaultZone());
|
||||||
AddDataMessage dataMessage1 = new AddDataMessage(protectedStorageEntry);
|
AddDataMessage dataMessage1 = new AddDataMessage(protectedStorageEntry);
|
||||||
|
|
|
@ -35,7 +35,8 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class ProtectedMailboxStorageEntryTest {
|
public class ProtectedMailboxStorageEntryTest {
|
||||||
|
|
||||||
|
@ -51,7 +52,10 @@ public class ProtectedMailboxStorageEntryTest {
|
||||||
when(prefixedSealedAndSignedMessageMock.toProtoNetworkEnvelope()).thenReturn(networkEnvelopeMock);
|
when(prefixedSealedAndSignedMessageMock.toProtoNetworkEnvelope()).thenReturn(networkEnvelopeMock);
|
||||||
|
|
||||||
return new MailboxStoragePayload(
|
return new MailboxStoragePayload(
|
||||||
prefixedSealedAndSignedMessageMock, payloadSenderPubKeyForAddOperation, payloadOwnerPubKey);
|
prefixedSealedAndSignedMessageMock,
|
||||||
|
payloadSenderPubKeyForAddOperation,
|
||||||
|
payloadOwnerPubKey,
|
||||||
|
MailboxStoragePayload.TTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ProtectedMailboxStorageEntry buildProtectedMailboxStorageEntry(
|
private static ProtectedMailboxStorageEntry buildProtectedMailboxStorageEntry(
|
||||||
|
|
|
@ -67,7 +67,10 @@ public class ProtectedStorageEntryTest {
|
||||||
when(prefixedSealedAndSignedMessageMock.toProtoNetworkEnvelope()).thenReturn(networkEnvelopeMock);
|
when(prefixedSealedAndSignedMessageMock.toProtoNetworkEnvelope()).thenReturn(networkEnvelopeMock);
|
||||||
|
|
||||||
return new MailboxStoragePayload(
|
return new MailboxStoragePayload(
|
||||||
prefixedSealedAndSignedMessageMock, payloadSenderPubKeyForAddOperation, payloadOwnerPubKey);
|
prefixedSealedAndSignedMessageMock,
|
||||||
|
payloadSenderPubKeyForAddOperation,
|
||||||
|
payloadOwnerPubKey,
|
||||||
|
MailboxStoragePayload.TTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
Loading…
Add table
Reference in a new issue