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:
chimp1984 2021-01-11 14:56:28 -05:00
parent 7a2501ea1b
commit 35ef3b842f
No known key found for this signature in database
GPG key ID: 9801B4EC591F90E3
11 changed files with 65 additions and 18 deletions

View file

@ -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) {

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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],

View file

@ -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);
} }

View file

@ -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;
} }
} }

View file

@ -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);

View file

@ -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(

View file

@ -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