mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-21 22:31:44 +01:00
Merge pull request #4025 from stejbac/make-persistence-thread-safe
Make serialisation in FileManager::saveToFile thread-safe
This commit is contained in:
commit
557ec7f449
31 changed files with 214 additions and 90 deletions
|
@ -21,7 +21,6 @@ import bisq.common.util.CollectionUtils;
|
|||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -36,7 +35,7 @@ import lombok.Setter;
|
|||
@Getter
|
||||
@Setter
|
||||
public class NavigationPath implements PersistableEnvelope {
|
||||
private List<String> path = new ArrayList<>();
|
||||
private List<String> path = List.of();
|
||||
|
||||
@Override
|
||||
public Message toProtoMessage() {
|
||||
|
@ -45,7 +44,7 @@ public class NavigationPath implements PersistableEnvelope {
|
|||
return protobuf.PersistableEnvelope.newBuilder().setNavigationPath(builder).build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.NavigationPath proto) {
|
||||
return new NavigationPath(new ArrayList<>(proto.getPathList()));
|
||||
public static NavigationPath fromProto(protobuf.NavigationPath proto) {
|
||||
return new NavigationPath(List.copyOf(proto.getPathList()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,14 @@ package bisq.common.proto.persistable;
|
|||
|
||||
import bisq.common.Envelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
/**
|
||||
* Interface for the outside envelope object persisted to disk.
|
||||
*/
|
||||
public interface PersistableEnvelope extends Envelope {
|
||||
|
||||
default Message toPersistableMessage() {
|
||||
return toProtoMessage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 bisq.common.proto.persistable;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
/**
|
||||
* Interface for the outer envelope object persisted to disk, where its serialization
|
||||
* during persistence takes place on a separate thread (for performance).
|
||||
* <p>
|
||||
* To make the serialization thread-safe, all modifications of the object must be
|
||||
* synchronized with it. This may be achieved by wrapping such modifications with the
|
||||
* provided {@link ThreadedPersistableEnvelope#modifySynchronized(Runnable)} method.
|
||||
*/
|
||||
public interface ThreadedPersistableEnvelope extends PersistableEnvelope {
|
||||
|
||||
@Override
|
||||
default Message toPersistableMessage() {
|
||||
synchronized (this) {
|
||||
return toProtoMessage();
|
||||
}
|
||||
}
|
||||
|
||||
default void modifySynchronized(Runnable modifyTask) {
|
||||
synchronized (this) {
|
||||
modifyTask.run();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 bisq.common.proto.persistable;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* Interface for the outer envelope object persisted to disk, where its serialization
|
||||
* during persistence is forced to take place on the user thread.
|
||||
* <p>
|
||||
* To avoid jitter, this should be only be used for small, safely critical stores. Larger
|
||||
* or frequently written stores should either implement {@link PersistableEnvelope}
|
||||
* directly (where thread-safety isn't needed) or use {@link ThreadedPersistableEnvelope}.
|
||||
*/
|
||||
public interface UserThreadMappedPersistableEnvelope extends PersistableEnvelope {
|
||||
|
||||
@Override
|
||||
default Message toPersistableMessage() {
|
||||
FutureTask<Message> toProtoOnUserThread = new FutureTask<>(this::toProtoMessage);
|
||||
UserThread.execute(toProtoOnUserThread);
|
||||
//noinspection UnstableApiUsage
|
||||
return Futures.getUnchecked(toProtoOnUserThread);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 bisq.common.proto.persistable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserThreadMappedPersistableList<T extends PersistablePayload> extends PersistableList<T>
|
||||
implements UserThreadMappedPersistableEnvelope {
|
||||
|
||||
public UserThreadMappedPersistableList(List<T> list) {
|
||||
super(list);
|
||||
}
|
||||
|
||||
public UserThreadMappedPersistableList() {
|
||||
}
|
||||
}
|
|
@ -189,7 +189,7 @@ public class FileManager<T extends PersistableEnvelope> {
|
|||
log.debug("Write to disc: {}", storageFile.getName());
|
||||
protobuf.PersistableEnvelope protoPersistable;
|
||||
try {
|
||||
protoPersistable = (protobuf.PersistableEnvelope) persistable.toProtoMessage();
|
||||
protoPersistable = (protobuf.PersistableEnvelope) persistable.toPersistableMessage();
|
||||
if (protoPersistable.toByteArray().length == 0)
|
||||
log.error("protoPersistable is empty. persistable=" + persistable.getClass().getSimpleName());
|
||||
} catch (Throwable e) {
|
||||
|
|
|
@ -21,7 +21,7 @@ package bisq.core.account.sign;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -40,7 +40,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class SignedWitnessStore implements PersistableEnvelope {
|
||||
public class SignedWitnessStore implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class SignedWitnessStore implements PersistableEnvelope {
|
|||
return protobuf.SignedWitnessStore.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.SignedWitnessStore proto) {
|
||||
public static SignedWitnessStore fromProto(protobuf.SignedWitnessStore proto) {
|
||||
List<SignedWitness> list = proto.getItemsList().stream()
|
||||
.map(SignedWitness::fromProto).collect(Collectors.toList());
|
||||
return new SignedWitnessStore(list);
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.account.witness;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class AccountAgeWitnessStore implements PersistableEnvelope {
|
||||
public class AccountAgeWitnessStore implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class AccountAgeWitnessStore implements PersistableEnvelope {
|
|||
return protobuf.AccountAgeWitnessStore.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.AccountAgeWitnessStore proto) {
|
||||
public static AccountAgeWitnessStore fromProto(protobuf.AccountAgeWitnessStore proto) {
|
||||
List<AccountAgeWitness> list = proto.getItemsList().stream()
|
||||
.map(AccountAgeWitness::fromProto).collect(Collectors.toList());
|
||||
return new AccountAgeWitnessStore(list);
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
package bisq.core.btc.model;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistedDataHost;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableEnvelope;
|
||||
import bisq.common.storage.Storage;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
@ -44,7 +44,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
*/
|
||||
@ToString
|
||||
@Slf4j
|
||||
public final class AddressEntryList implements PersistableEnvelope, PersistedDataHost {
|
||||
public final class AddressEntryList implements UserThreadMappedPersistableEnvelope, PersistedDataHost {
|
||||
transient private Storage<AddressEntryList> storage;
|
||||
transient private Wallet wallet;
|
||||
@Getter
|
||||
|
|
|
@ -19,8 +19,7 @@ package bisq.core.dao.governance.blindvote;
|
|||
|
||||
import bisq.core.dao.governance.ConsensusCritical;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -34,7 +33,7 @@ import lombok.EqualsAndHashCode;
|
|||
* List of my own blind votes. Blind votes received from other voters are stored in the BlindVoteStore.
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MyBlindVoteList extends PersistableList<BlindVote> implements ConsensusCritical {
|
||||
public class MyBlindVoteList extends UserThreadMappedPersistableList<BlindVote> implements ConsensusCritical {
|
||||
|
||||
MyBlindVoteList() {
|
||||
super();
|
||||
|
@ -59,7 +58,7 @@ public class MyBlindVoteList extends PersistableList<BlindVote> implements Conse
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.MyBlindVoteList proto) {
|
||||
public static MyBlindVoteList fromProto(protobuf.MyBlindVoteList proto) {
|
||||
return new MyBlindVoteList(new ArrayList<>(proto.getBlindVoteList().stream()
|
||||
.map(BlindVote::fromProto)
|
||||
.collect(Collectors.toList())));
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.dao.governance.blindvote.storage;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class BlindVoteStore implements PersistableEnvelope {
|
||||
public class BlindVoteStore implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class BlindVoteStore implements PersistableEnvelope {
|
|||
return protobuf.BlindVoteStore.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.BlindVoteStore proto) {
|
||||
public static BlindVoteStore fromProto(protobuf.BlindVoteStore proto) {
|
||||
List<BlindVotePayload> list = proto.getItemsList().stream()
|
||||
.map(BlindVotePayload::fromProto).collect(Collectors.toList());
|
||||
return new BlindVoteStore(list);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package bisq.core.dao.governance.bond.reputation;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -29,7 +29,7 @@ import lombok.EqualsAndHashCode;
|
|||
* PersistableEnvelope wrapper for list of MyReputations.
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MyReputationList extends PersistableList<MyReputation> {
|
||||
public class MyReputationList extends UserThreadMappedPersistableList<MyReputation> {
|
||||
|
||||
private MyReputationList(List<MyReputation> list) {
|
||||
super(list);
|
||||
|
@ -69,4 +69,3 @@ public class MyReputationList extends PersistableList<MyReputation> {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
|
||||
package bisq.core.dao.governance.myvote;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -29,9 +28,9 @@ import java.util.stream.Collectors;
|
|||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MyVoteList extends PersistableList<MyVote> {
|
||||
public class MyVoteList extends UserThreadMappedPersistableList<MyVote> {
|
||||
|
||||
public MyVoteList() {
|
||||
MyVoteList() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -53,7 +52,7 @@ public class MyVoteList extends PersistableList<MyVote> {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.MyVoteList proto) {
|
||||
public static MyVoteList fromProto(protobuf.MyVoteList proto) {
|
||||
return new MyVoteList(new ArrayList<>(proto.getMyVoteList().stream()
|
||||
.map(MyVote::fromProto)
|
||||
.collect(Collectors.toList())));
|
||||
|
@ -66,4 +65,3 @@ public class MyVoteList extends PersistableList<MyVote> {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package bisq.core.dao.governance.proofofburn;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -29,7 +29,7 @@ import lombok.EqualsAndHashCode;
|
|||
* PersistableEnvelope wrapper for list of MyProofOfBurn objects.
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MyProofOfBurnList extends PersistableList<MyProofOfBurn> {
|
||||
public class MyProofOfBurnList extends UserThreadMappedPersistableList<MyProofOfBurn> {
|
||||
|
||||
private MyProofOfBurnList(List<MyProofOfBurn> list) {
|
||||
super(list);
|
||||
|
@ -69,4 +69,3 @@ public class MyProofOfBurnList extends PersistableList<MyProofOfBurn> {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.dao.governance.proposal;
|
|||
import bisq.core.dao.governance.ConsensusCritical;
|
||||
import bisq.core.dao.state.model.governance.Proposal;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -32,7 +32,7 @@ import lombok.EqualsAndHashCode;
|
|||
* PersistableEnvelope wrapper for list of proposals. Used in vote consensus, so changes can break consensus!
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MyProposalList extends PersistableList<Proposal> implements ConsensusCritical {
|
||||
public class MyProposalList extends UserThreadMappedPersistableList<Proposal> implements ConsensusCritical {
|
||||
|
||||
public MyProposalList(List<Proposal> list) {
|
||||
super(list);
|
||||
|
@ -72,4 +72,3 @@ public class MyProposalList extends PersistableList<Proposal> implements Consens
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.dao.governance.proposal.storage.appendonly;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class ProposalStore implements PersistableEnvelope {
|
||||
public class ProposalStore implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class ProposalStore implements PersistableEnvelope {
|
|||
return protobuf.ProposalStore.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.ProposalStore proto) {
|
||||
public static ProposalStore fromProto(protobuf.ProposalStore proto) {
|
||||
List<ProposalPayload> list = proto.getItemsList().stream()
|
||||
.map(ProposalPayload::fromProto).collect(Collectors.toList());
|
||||
return new ProposalStore(list);
|
||||
|
|
|
@ -21,7 +21,7 @@ import bisq.network.p2p.storage.P2PDataStorage;
|
|||
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
|
||||
|
||||
import bisq.common.proto.network.NetworkProtoResolver;
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -42,7 +42,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class TempProposalStore implements PersistableEnvelope {
|
||||
public class TempProposalStore implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, ProtectedStorageEntry> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class TempProposalStore implements PersistableEnvelope {
|
|||
return protobuf.TempProposalStore.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.TempProposalStore proto, NetworkProtoResolver networkProtoResolver) {
|
||||
public static TempProposalStore fromProto(protobuf.TempProposalStore proto, NetworkProtoResolver networkProtoResolver) {
|
||||
List<ProtectedStorageEntry> list = proto.getItemsList().stream()
|
||||
.map(entry -> ProtectedStorageEntry.fromProto(entry, networkProtoResolver))
|
||||
.collect(Collectors.toList());
|
||||
|
|
|
@ -86,8 +86,10 @@ public class DaoStateStorageService extends StoreService<DaoStateStore> {
|
|||
}
|
||||
|
||||
private void persist(DaoState daoState, LinkedList<DaoStateHash> daoStateHashChain, long delayInMilli) {
|
||||
store.setDaoState(daoState);
|
||||
store.setDaoStateHashChain(daoStateHashChain);
|
||||
store.modifySynchronized(() -> {
|
||||
store.setDaoState(daoState);
|
||||
store.setDaoStateHashChain(daoStateHashChain);
|
||||
});
|
||||
storage.queueUpForSave(store, delayInMilli);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.dao.state;
|
|||
import bisq.core.dao.monitoring.model.DaoStateHash;
|
||||
import bisq.core.dao.state.model.DaoState;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
|
||||
@Slf4j
|
||||
public class DaoStateStore implements PersistableEnvelope {
|
||||
public class DaoStateStore implements ThreadedPersistableEnvelope {
|
||||
// DaoState is always a clone and must not be used for read access beside initial read from disc when we apply
|
||||
// the snapshot!
|
||||
@Getter
|
||||
|
@ -67,7 +67,7 @@ public class DaoStateStore implements PersistableEnvelope {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.DaoStateStore proto) {
|
||||
public static DaoStateStore fromProto(protobuf.DaoStateStore proto) {
|
||||
LinkedList<DaoStateHash> daoStateHashList = proto.getDaoStateHashList().isEmpty() ?
|
||||
new LinkedList<>() :
|
||||
new LinkedList<>(proto.getDaoStateHashList().stream()
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.dao.state.model.governance;
|
|||
import bisq.core.dao.governance.ConsensusCritical;
|
||||
import bisq.core.dao.state.model.ImmutableDaoStateModel;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -35,7 +35,7 @@ import javax.annotation.concurrent.Immutable;
|
|||
*/
|
||||
@Immutable
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BallotList extends PersistableList<Ballot> implements ConsensusCritical, ImmutableDaoStateModel {
|
||||
public class BallotList extends UserThreadMappedPersistableList<Ballot> implements ConsensusCritical, ImmutableDaoStateModel {
|
||||
|
||||
public BallotList(List<Ballot> list) {
|
||||
super(list);
|
||||
|
@ -75,4 +75,3 @@ public class BallotList extends PersistableList<Ballot> implements ConsensusCrit
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
|
||||
package bisq.core.dao.state.unconfirmed;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -29,7 +28,7 @@ import java.util.stream.Collectors;
|
|||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UnconfirmedBsqChangeOutputList extends PersistableList<UnconfirmedTxOutput> {
|
||||
public class UnconfirmedBsqChangeOutputList extends UserThreadMappedPersistableList<UnconfirmedTxOutput> {
|
||||
|
||||
UnconfirmedBsqChangeOutputList() {
|
||||
super();
|
||||
|
@ -52,7 +51,7 @@ public class UnconfirmedBsqChangeOutputList extends PersistableList<UnconfirmedT
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.UnconfirmedBsqChangeOutputList proto) {
|
||||
public static UnconfirmedBsqChangeOutputList fromProto(protobuf.UnconfirmedBsqChangeOutputList proto) {
|
||||
return new UnconfirmedBsqChangeOutputList(new ArrayList<>(proto.getUnconfirmedTxOutputList().stream()
|
||||
.map(UnconfirmedTxOutput::fromProto)
|
||||
.collect(Collectors.toList())));
|
||||
|
|
|
@ -19,8 +19,7 @@ package bisq.core.payment;
|
|||
|
||||
import bisq.core.proto.CoreProtoResolver;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableList;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -31,7 +30,7 @@ import java.util.stream.Collectors;
|
|||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PaymentAccountList extends PersistableList<PaymentAccount> {
|
||||
public class PaymentAccountList extends UserThreadMappedPersistableList<PaymentAccount> {
|
||||
|
||||
public PaymentAccountList(List<PaymentAccount> list) {
|
||||
super(list);
|
||||
|
@ -45,7 +44,7 @@ public class PaymentAccountList extends PersistableList<PaymentAccount> {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.PaymentAccountList proto, CoreProtoResolver coreProtoResolver) {
|
||||
public static PaymentAccountList fromProto(protobuf.PaymentAccountList proto, CoreProtoResolver coreProtoResolver) {
|
||||
return new PaymentAccountList(new ArrayList<>(proto.getPaymentAccountList().stream()
|
||||
.map(e -> PaymentAccount.fromProto(e, coreProtoResolver))
|
||||
.collect(Collectors.toList())));
|
||||
|
|
|
@ -19,6 +19,7 @@ package bisq.core.support.dispute;
|
|||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistedDataHost;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableEnvelope;
|
||||
import bisq.common.storage.Storage;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -39,7 +40,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* Calls to the List are delegated because this class intercepts the add/remove calls so changes
|
||||
* can be saved to disc.
|
||||
*/
|
||||
public abstract class DisputeList<T extends PersistableEnvelope> implements PersistableEnvelope, PersistedDataHost {
|
||||
public abstract class DisputeList<T extends PersistableEnvelope> implements UserThreadMappedPersistableEnvelope, PersistedDataHost {
|
||||
transient protected final Storage<T> storage;
|
||||
|
||||
@Getter
|
||||
|
|
|
@ -23,7 +23,7 @@ import bisq.core.proto.CoreProtoResolver;
|
|||
|
||||
import bisq.common.proto.ProtoUtil;
|
||||
import bisq.common.proto.ProtobufferRuntimeException;
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableEnvelope;
|
||||
import bisq.common.storage.Storage;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
@ -41,7 +41,7 @@ import lombok.Getter;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public final class TradableList<T extends Tradable> implements PersistableEnvelope {
|
||||
public final class TradableList<T extends Tradable> implements UserThreadMappedPersistableEnvelope {
|
||||
transient final private Storage<TradableList<T>> storage;
|
||||
@Getter
|
||||
private final ObservableList<T> list = FXCollections.observableArrayList();
|
||||
|
@ -78,10 +78,10 @@ public final class TradableList<T extends Tradable> implements PersistableEnvelo
|
|||
.build();
|
||||
}
|
||||
|
||||
public static TradableList fromProto(protobuf.TradableList proto,
|
||||
CoreProtoResolver coreProtoResolver,
|
||||
Storage<TradableList<Tradable>> storage,
|
||||
BtcWalletService btcWalletService) {
|
||||
public static TradableList<Tradable> fromProto(protobuf.TradableList proto,
|
||||
CoreProtoResolver coreProtoResolver,
|
||||
Storage<TradableList<Tradable>> storage,
|
||||
BtcWalletService btcWalletService) {
|
||||
List<Tradable> list = proto.getTradableList().stream()
|
||||
.map(tradable -> {
|
||||
switch (tradable.getMessageCase()) {
|
||||
|
|
|
@ -20,7 +20,7 @@ package bisq.core.trade.statistics;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -38,7 +38,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
* definition and provide a hashMap for the domain access.
|
||||
*/
|
||||
@Slf4j
|
||||
public class TradeStatistics2Store implements PersistableEnvelope {
|
||||
public class TradeStatistics2Store implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class TradeStatistics2Store implements PersistableEnvelope {
|
|||
return protobuf.TradeStatistics2Store.newBuilder().addAllItems(protoList);
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.TradeStatistics2Store proto) {
|
||||
public static TradeStatistics2Store fromProto(protobuf.TradeStatistics2Store proto) {
|
||||
List<TradeStatistics2> list = proto.getItemsList().stream()
|
||||
.map(TradeStatistics2::fromProto).collect(Collectors.toList());
|
||||
return new TradeStatistics2Store(list);
|
||||
|
|
|
@ -25,7 +25,7 @@ import bisq.core.payment.PaymentAccount;
|
|||
import bisq.core.proto.CoreProtoResolver;
|
||||
|
||||
import bisq.common.proto.ProtoUtil;
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -49,7 +49,7 @@ import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAs
|
|||
@Slf4j
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public final class PreferencesPayload implements PersistableEnvelope {
|
||||
public final class PreferencesPayload implements UserThreadMappedPersistableEnvelope {
|
||||
private String userLanguage;
|
||||
private Country userCountry;
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
|
@ -132,7 +132,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public PreferencesPayload() {
|
||||
PreferencesPayload() {
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,7 +207,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||
return protobuf.PersistableEnvelope.newBuilder().setPreferencesPayload(builder).build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.PreferencesPayload proto, CoreProtoResolver coreProtoResolver) {
|
||||
public static PreferencesPayload fromProto(protobuf.PreferencesPayload proto, CoreProtoResolver coreProtoResolver) {
|
||||
final protobuf.Country userCountry = proto.getUserCountry();
|
||||
PaymentAccount paymentAccount = null;
|
||||
if (proto.hasSelectedPaymentAccountForCreateOffer() && proto.getSelectedPaymentAccountForCreateOffer().hasPaymentMethod())
|
||||
|
@ -275,6 +275,5 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||
proto.getBuyerSecurityDepositAsPercentForCrypto(),
|
||||
proto.getBlockNotifyPort(),
|
||||
proto.getTacAcceptedV120());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import bisq.core.support.dispute.mediation.mediator.Mediator;
|
|||
import bisq.core.support.dispute.refund.refundagent.RefundAgent;
|
||||
|
||||
import bisq.common.proto.ProtoUtil;
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.UserThreadMappedPersistableEnvelope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
@ -46,7 +46,7 @@ import javax.annotation.Nullable;
|
|||
@Slf4j
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class UserPayload implements PersistableEnvelope {
|
||||
public class UserPayload implements UserThreadMappedPersistableEnvelope {
|
||||
@Nullable
|
||||
private String accountId;
|
||||
@Nullable
|
||||
|
|
|
@ -141,7 +141,7 @@ public final class Navigation implements PersistedDataHost {
|
|||
|
||||
private void queueUpForSave() {
|
||||
if (currentPath.tip() != null) {
|
||||
navigationPath.setPath(currentPath.stream().map(Class::getName).collect(Collectors.toList()));
|
||||
navigationPath.setPath(currentPath.stream().map(Class::getName).collect(Collectors.toUnmodifiableList()));
|
||||
}
|
||||
storage.queueUpForSave(navigationPath, 1000);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package bisq.network.p2p.peers.peerexchange;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistableList;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -27,23 +26,30 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PeerList extends PersistableList<Peer> {
|
||||
@EqualsAndHashCode
|
||||
public class PeerList implements PersistableEnvelope {
|
||||
@Getter
|
||||
private final List<Peer> list;
|
||||
|
||||
public PeerList(List<Peer> list) {
|
||||
super(list);
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message toProtoMessage() {
|
||||
return protobuf.PersistableEnvelope.newBuilder()
|
||||
.setPeerList(protobuf.PeerList.newBuilder()
|
||||
.addAllPeer(getList().stream().map(Peer::toProtoMessage).collect(Collectors.toList())))
|
||||
.addAllPeer(list.stream().map(Peer::toProtoMessage).collect(Collectors.toList())))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.PeerList proto) {
|
||||
public static PeerList fromProto(protobuf.PeerList proto) {
|
||||
return new PeerList(new ArrayList<>(proto.getPeerList().stream()
|
||||
.map(Peer::fromProto)
|
||||
.collect(Collectors.toList())));
|
||||
|
|
|
@ -20,8 +20,8 @@ package bisq.network.p2p.storage.persistence;
|
|||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.PersistenceProtoResolver;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
|
@ -42,11 +42,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||
// TODO at next hard fork we can rename the PB definition and class name.
|
||||
@Deprecated
|
||||
@Slf4j
|
||||
public class PersistableNetworkPayloadList implements PersistableEnvelope {
|
||||
public class PersistableNetworkPayloadList implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
|
||||
|
||||
public PersistableNetworkPayloadList() {
|
||||
PersistableNetworkPayloadList() {
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,7 +54,7 @@ public class PersistableNetworkPayloadList implements PersistableEnvelope {
|
|||
// PROTO BUFFER
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public PersistableNetworkPayloadList(Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map) {
|
||||
private PersistableNetworkPayloadList(Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map) {
|
||||
this.map.putAll(map);
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,8 @@ public class PersistableNetworkPayloadList implements PersistableEnvelope {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static PersistableEnvelope fromProto(protobuf.PersistableNetworkPayloadList proto,
|
||||
PersistenceProtoResolver resolver) {
|
||||
public static PersistableNetworkPayloadList fromProto(protobuf.PersistableNetworkPayloadList proto,
|
||||
PersistenceProtoResolver resolver) {
|
||||
Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new HashMap<>();
|
||||
proto.getItemsList()
|
||||
.forEach(e -> {
|
||||
|
|
|
@ -19,7 +19,7 @@ package bisq.network.p2p.storage.persistence;
|
|||
|
||||
import bisq.network.p2p.storage.P2PDataStorage;
|
||||
|
||||
import bisq.common.proto.persistable.PersistableEnvelope;
|
||||
import bisq.common.proto.persistable.ThreadedPersistableEnvelope;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -34,7 +34,7 @@ import lombok.Setter;
|
|||
* in protobuffer the map construct can't be anything, so the straightforward mapping was not possible.
|
||||
* Hence this Persistable class.
|
||||
*/
|
||||
public class SequenceNumberMap implements PersistableEnvelope {
|
||||
public class SequenceNumberMap implements ThreadedPersistableEnvelope {
|
||||
@Getter
|
||||
@Setter
|
||||
private Map<P2PDataStorage.ByteArray, P2PDataStorage.MapValue> map = new ConcurrentHashMap<>();
|
||||
|
@ -70,7 +70,7 @@ public class SequenceNumberMap implements PersistableEnvelope {
|
|||
|
||||
public static SequenceNumberMap fromProto(protobuf.SequenceNumberMap proto) {
|
||||
HashMap<P2PDataStorage.ByteArray, P2PDataStorage.MapValue> map = new HashMap<>();
|
||||
proto.getSequenceNumberEntriesList().stream()
|
||||
proto.getSequenceNumberEntriesList()
|
||||
.forEach(e -> map.put(P2PDataStorage.ByteArray.fromProto(e.getBytes()), P2PDataStorage.MapValue.fromProto(e.getMapValue())));
|
||||
return new SequenceNumberMap(map);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue