Add domain layer for signed account age witnesses (credits ManfredKarrer and oscarguindzberg)

This commit is contained in:
Christoph Atteneder 2019-06-06 16:04:13 +02:00 committed by Christoph Sturm
parent 4b235dbadb
commit fdf5364c47
83 changed files with 998 additions and 83 deletions

View file

@ -33,5 +33,6 @@ public enum Capability {
ACK_MSG,
BSQ_BLOCK,
DAO_STATE,
BUNDLE_OF_ENVELOPES
BUNDLE_OF_ENVELOPES,
SIGNED_ACCOUNT_AGE_WITNESS
}

View file

@ -111,7 +111,7 @@ public class Sig {
sig.update(data);
return sig.verify(signature);
} catch (SignatureException | InvalidKeyException | NoSuchAlgorithmException e) {
throw new CryptoException("Signature verification failed. " + e.getMessage());
throw new CryptoException("Signature verification failed", e);
}
}

View file

@ -438,6 +438,7 @@ message PersistableNetworkPayload {
TradeStatistics2 trade_statistics2 = 2;
ProposalPayload proposal_payload = 3;
BlindVotePayload blind_vote_payload = 4;
SignedWitness signed_witness = 5;
}
}
@ -639,6 +640,16 @@ message AccountAgeWitness {
int64 date = 2;
}
message SignedWitness {
bool signed_by_arbitrator = 1;
bytes witness_hash = 2;
bytes signature = 3;
bytes signer_pub_key = 4;
bytes witness_owner_pub_key = 5;
int64 date = 6;
int64 trade_amount = 7;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Dispute payload
///////////////////////////////////////////////////////////////////////////////////////////
@ -1020,6 +1031,7 @@ message PersistableEnvelope {
MyReputationList my_reputation_list = 25;
MyProofOfBurnList my_proof_of_burn_list = 26;
UnconfirmedBsqChangeOutputList unconfirmed_bsq_change_output_list = 27;
SignedWitnessStore signed_witness_store = 28;
}
}
@ -1060,6 +1072,10 @@ message AccountAgeWitnessStore {
repeated AccountAgeWitness items = 1;
}
message SignedWitnessStore {
repeated SignedWitness items = 1;
}
// We use a list not a hash map to save disc space. The hash can be calculated from the payload anyway
message TradeStatistics2Store {
repeated TradeStatistics2 items = 1;

View file

@ -0,0 +1,169 @@
/*
* 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.core.account.sign;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.network.p2p.storage.payload.DateTolerantPayload;
import bisq.network.p2p.storage.payload.LazyProcessedPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.crypto.Hash;
import bisq.common.proto.persistable.PersistableEnvelope;
import bisq.common.util.Utilities;
import com.google.protobuf.ByteString;
import org.bitcoinj.core.Coin;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
// Supports signatures made from EC key (arbitrators) and signature created with DSA key.
@Slf4j
@Value
public class SignedWitness implements LazyProcessedPayload, PersistableNetworkPayload, PersistableEnvelope,
DateTolerantPayload, CapabilityRequiringPayload {
private static final long TOLERANCE = TimeUnit.DAYS.toMillis(1);
private final boolean signedByArbitrator;
private final byte[] witnessHash;
private final byte[] signature;
private final byte[] signerPubKey;
private final byte[] witnessOwnerPubKey;
private final long date;
private final long tradeAmount;
transient private final byte[] hash;
public SignedWitness(boolean signedByArbitrator,
byte[] witnessHash,
byte[] signature,
byte[] signerPubKey,
byte[] witnessOwnerPubKey,
long date,
long tradeAmount) {
this.signedByArbitrator = signedByArbitrator;
this.witnessHash = witnessHash;
this.signature = signature;
this.signerPubKey = signerPubKey;
this.witnessOwnerPubKey = witnessOwnerPubKey;
this.date = date;
this.tradeAmount = tradeAmount;
// The hash is only using the data which do not change in repeated trades between same users (no date or amount).
// We only want to store the first and oldest one and will ignore others. That will help also to protect privacy
// so that the total number of trades is not revealed. We use putIfAbsent when we store the data so first
// object will win. We consider one signed trade with one peer enough and do not consider repeated trades with
// same peer to add more security as if that one would be colluding it would be not detected anyway. The total
// number of signed trades with different peers is still available and can be considered more valuable data for
// security.
byte[] data = Utilities.concatenateByteArrays(witnessHash, signature);
data = Utilities.concatenateByteArrays(data, signerPubKey);
hash = Hash.getSha256Ripemd160hash(data);
}
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public protobuf.PersistableNetworkPayload toProtoMessage() {
final protobuf.SignedWitness.Builder builder = protobuf.SignedWitness.newBuilder()
.setSignedByArbitrator(signedByArbitrator)
.setWitnessHash(ByteString.copyFrom(witnessHash))
.setSignature(ByteString.copyFrom(signature))
.setSignerPubKey(ByteString.copyFrom(signerPubKey))
.setWitnessOwnerPubKey(ByteString.copyFrom(witnessOwnerPubKey))
.setDate(date)
.setTradeAmount(tradeAmount);
return protobuf.PersistableNetworkPayload.newBuilder().setSignedWitness(builder).build();
}
public protobuf.SignedWitness toProtoSignedWitness() {
return toProtoMessage().getSignedWitness();
}
public static SignedWitness fromProto(protobuf.SignedWitness proto) {
return new SignedWitness(proto.getSignedByArbitrator(),
proto.getWitnessHash().toByteArray(),
proto.getSignature().toByteArray(),
proto.getSignerPubKey().toByteArray(),
proto.getWitnessOwnerPubKey().toByteArray(),
proto.getDate(),
proto.getTradeAmount());
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public boolean isDateInTolerance() {
// We don't allow older or newer then 1 day.
// Preventing forward dating is also important to protect against a sophisticated attack
return Math.abs(new Date().getTime() - date) <= TOLERANCE;
}
@Override
public boolean verifyHashSize() {
return hash.length == 20;
}
// Pre 1.0.1 version don't know the new message type and throw an error which leads to disconnecting the peer.
@Override
public Capabilities getRequiredCapabilities() {
return new Capabilities(Capability.SIGNED_ACCOUNT_AGE_WITNESS);
}
@Override
public byte[] getHash() {
return hash;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public P2PDataStorage.ByteArray getHashAsByteArray() {
return new P2PDataStorage.ByteArray(hash);
}
@Override
public String toString() {
return "SignedWitness{" +
",\n signedByArbitrator=" + signedByArbitrator +
",\n witnessHash=" + Utilities.bytesAsHexString(witnessHash) +
",\n signature=" + Utilities.bytesAsHexString(signature) +
",\n signerPubKey=" + Utilities.bytesAsHexString(signerPubKey) +
",\n witnessOwnerPubKey=" + Utilities.bytesAsHexString(witnessOwnerPubKey) +
",\n date=" + date +
",\n tradeAmount=" + Coin.valueOf(tradeAmount).toFriendlyString() +
",\n hash=" + Utilities.bytesAsHexString(hash) +
"\n}";
}
}

View file

@ -0,0 +1,298 @@
/*
* 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.core.account.sign;
import bisq.core.account.witness.AccountAgeWitness;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.persistence.AppendOnlyDataStoreService;
import bisq.common.crypto.CryptoException;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.Sig;
import bisq.common.util.Utilities;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import javax.inject.Inject;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import java.security.PublicKey;
import java.security.SignatureException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SignedWitnessService {
public static final long CHARGEBACK_SAFETY_DAYS = 30;
private final KeyRing keyRing;
private final P2PService p2PService;
private final AccountAgeWitnessService accountAgeWitnessService;
private final ArbitratorManager arbitratorManager;
private final Map<P2PDataStorage.ByteArray, SignedWitness> signedWitnessMap = new HashMap<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public SignedWitnessService(KeyRing keyRing,
P2PService p2PService,
AccountAgeWitnessService accountAgeWitnessService,
ArbitratorManager arbitratorManager,
SignedWitnessStorageService signedWitnessStorageService,
AppendOnlyDataStoreService appendOnlyDataStoreService) {
this.keyRing = keyRing;
this.p2PService = p2PService;
this.accountAgeWitnessService = accountAgeWitnessService;
this.arbitratorManager = arbitratorManager;
// We need to add that early (before onAllServicesInitialized) as it will be used at startup.
appendOnlyDataStoreService.addService(signedWitnessStorageService);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
public void onAllServicesInitialized() {
p2PService.getP2PDataStorage().addAppendOnlyDataStoreListener(payload -> {
if (payload instanceof SignedWitness)
addToMap((SignedWitness) payload);
});
// At startup the P2PDataStorage initializes earlier, otherwise we ge the listener called.
p2PService.getP2PDataStorage().getAppendOnlyDataStoreMap().values().forEach(e -> {
if (e instanceof SignedWitness)
addToMap((SignedWitness) e);
});
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
public List<Long> getMyWitnessAgeList(PaymentAccountPayload myPaymentAccountPayload) {
AccountAgeWitness accountAgeWitness = accountAgeWitnessService.getMyWitness(myPaymentAccountPayload);
// We do not validate as it would not make sense to cheat one self...
return getSignedWitnessSet(accountAgeWitness).stream()
.map(SignedWitness::getDate)
.sorted()
.collect(Collectors.toList());
}
public List<Long> getVerifiedWitnessAgeList(AccountAgeWitness accountAgeWitness) {
return signedWitnessMap.values().stream()
.filter(e -> Arrays.equals(e.getWitnessHash(), accountAgeWitness.getHash()))
.filter(this::verifySignature)
.map(SignedWitness::getDate)
.sorted()
.collect(Collectors.toList());
}
// Arbitrators sign with EC key
public SignedWitness signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness accountAgeWitness, ECKey key, PublicKey peersPubKey) {
String accountAgeWitnessHashAsHex = Utilities.encodeToHex(accountAgeWitness.getHash());
String signatureBase64 = key.signMessage(accountAgeWitnessHashAsHex);
return new SignedWitness(true,
accountAgeWitness.getHash(),
signatureBase64.getBytes(Charsets.UTF_8),
key.getPubKey(),
peersPubKey.getEncoded(),
new Date().getTime(),
tradeAmount.value);
}
// Any peer can sign with DSA key
public SignedWitness signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness accountAgeWitness, PublicKey peersPubKey) throws CryptoException {
byte[] signature = Sig.sign(keyRing.getSignatureKeyPair().getPrivate(), accountAgeWitness.getHash());
return new SignedWitness(false,
accountAgeWitness.getHash(),
signature,
keyRing.getSignatureKeyPair().getPublic().getEncoded(),
peersPubKey.getEncoded(),
new Date().getTime(),
tradeAmount.value);
}
public boolean verifySignature(SignedWitness signedWitness) {
if (signedWitness.isSignedByArbitrator()) {
return verifySignatureWithECKey(signedWitness);
} else {
return verifySignatureWithDSAKey(signedWitness);
}
}
private boolean verifySignatureWithECKey(SignedWitness signedWitness) {
try {
String message = Utilities.encodeToHex(signedWitness.getWitnessHash());
String signatureBase64 = new String(signedWitness.getSignature(), Charsets.UTF_8);
ECKey key = ECKey.fromPublicOnly(signedWitness.getSignerPubKey());
if (arbitratorManager.isPublicKeyInList(Utilities.encodeToHex(key.getPubKey()))) {
key.verifyMessage(message, signatureBase64);
return true;
} else {
log.warn("Provided EC key is not in list of valid arbitrators.");
return false;
}
} catch (SignatureException e) {
log.warn("verifySignature signedWitness failed. signedWitness={}", signedWitness);
log.warn("Caused by ", e);
return false;
}
}
private boolean verifySignatureWithDSAKey(SignedWitness signedWitness) {
try {
PublicKey signaturePubKey = Sig.getPublicKeyFromBytes(signedWitness.getSignerPubKey());
Sig.verify(signaturePubKey, signedWitness.getWitnessHash(), signedWitness.getSignature());
return true;
} catch (CryptoException e) {
log.warn("verifySignature signedWitness failed. signedWitness={}", signedWitness);
log.warn("Caused by ", e);
return false;
}
}
public Set<SignedWitness> getSignedWitnessSet(AccountAgeWitness accountAgeWitness) {
return signedWitnessMap.values().stream()
.filter(e -> Arrays.equals(e.getWitnessHash(), accountAgeWitness.getHash()))
.collect(Collectors.toSet());
}
// SignedWitness objects signed by arbitrators
public Set<SignedWitness> getArbitratorsSignedWitnessSet(AccountAgeWitness accountAgeWitness) {
return signedWitnessMap.values().stream()
.filter(SignedWitness::isSignedByArbitrator)
.filter(e -> Arrays.equals(e.getWitnessHash(), accountAgeWitness.getHash()))
.collect(Collectors.toSet());
}
// SignedWitness objects signed by any other peer
public Set<SignedWitness> getTrustedPeerSignedWitnessSet(AccountAgeWitness accountAgeWitness) {
return signedWitnessMap.values().stream()
.filter(e -> !e.isSignedByArbitrator())
.filter(e -> Arrays.equals(e.getWitnessHash(), accountAgeWitness.getHash()))
.collect(Collectors.toSet());
}
// We go one level up by using the signer Key to lookup for SignedWitness objects which contain the signerKey as
// witnessOwnerPubKey
public Set<SignedWitness> getSignedWitnessSetByOwnerPubKey(byte[] ownerPubKey, Stack<P2PDataStorage.ByteArray> excluded) {
return signedWitnessMap.values().stream()
.filter(e -> Arrays.equals(e.getWitnessOwnerPubKey(), ownerPubKey))
.filter(e -> !excluded.contains(new P2PDataStorage.ByteArray(e.getSignerPubKey())))
.collect(Collectors.toSet());
}
/**
* Checks whether the accountAgeWitness has a valid signature from a peer/arbitrator.
* @param accountAgeWitness
* @return true if accountAgeWitness is valid, false otherwise.
*/
public boolean isValidAccountAgeWitness(AccountAgeWitness accountAgeWitness) {
Stack<P2PDataStorage.ByteArray> excludedPubKeys = new Stack<>();
long now = new Date().getTime();
Set<SignedWitness> signedWitnessSet = getSignedWitnessSet(accountAgeWitness);
for (SignedWitness signedWitness : signedWitnessSet) {
if (isValidSignedWitnessInternal(signedWitness, now, excludedPubKeys)) {
return true;
}
}
// If we have not returned in the loops or they have been empty we have not found a valid signer.
return false;
}
/**
* Helper to isValidAccountAgeWitness(accountAgeWitness)
* @param signedWitness the signedWitness to validate
* @param childSignedWitnessDateMillis the date the child SignedWitness was signed or current time if it is a leave.
* @param excludedPubKeys stack to preventsrecursive loops
* @return true if signedWitness is valid, false otherwise.
*/
private boolean isValidSignedWitnessInternal(SignedWitness signedWitness, long childSignedWitnessDateMillis, Stack<P2PDataStorage.ByteArray> excludedPubKeys) {
if (!verifySignature(signedWitness)) {
return false;
}
if (signedWitness.isSignedByArbitrator()) {
// If signed by an arbitrator we don't have to check anything else.
return true;
} else {
if (!verifyDate(signedWitness, childSignedWitnessDateMillis)) {
return false;
}
if (excludedPubKeys.size() >= 2000) {
// Prevent DoS attack: an attacker floods the SignedWitness db with a long chain that takes lots of time to verify.ca
return false;
}
excludedPubKeys.push(new P2PDataStorage.ByteArray(signedWitness.getSignerPubKey()));
excludedPubKeys.push(new P2PDataStorage.ByteArray(signedWitness.getWitnessOwnerPubKey()));
// Iterate over signedWitness signers
Set<SignedWitness> signerSignedWitnessSet = getSignedWitnessSetByOwnerPubKey(signedWitness.getSignerPubKey(), excludedPubKeys);
for (SignedWitness signerSignedWitness : signerSignedWitnessSet) {
if (isValidSignedWitnessInternal(signerSignedWitness, signedWitness.getDate(), excludedPubKeys)) {
return true;
}
}
excludedPubKeys.pop();
excludedPubKeys.pop();
}
// If we have not returned in the loops or they have been empty we have not found a valid signer.
return false;
}
private boolean verifyDate(SignedWitness signedWitness, long childSignedWitnessDateMillis) {
long childSignedWitnessDateMinusChargebackPeriodMillis = Instant.ofEpochMilli(childSignedWitnessDateMillis).minus(CHARGEBACK_SAFETY_DAYS, ChronoUnit.DAYS).toEpochMilli();
long signedWitnessDateMillis = signedWitness.getDate();
return signedWitnessDateMillis <= childSignedWitnessDateMinusChargebackPeriodMillis;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
@VisibleForTesting
void addToMap(SignedWitness signedWitness) {
signedWitnessMap.putIfAbsent(signedWitness.getHashAsByteArray(), signedWitness);
}
}

View file

@ -0,0 +1,89 @@
/*
* 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.core.account.sign;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.network.p2p.storage.persistence.MapStoreService;
import bisq.common.storage.Storage;
import com.google.inject.name.Named;
import javax.inject.Inject;
import java.io.File;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j
public class SignedWitnessStorageService extends MapStoreService<SignedWitnessStore, PersistableNetworkPayload> {
private static final String FILE_NAME = "SignedWitnessStore";
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public SignedWitnessStorageService(@Named(Storage.STORAGE_DIR) File storageDir,
Storage<SignedWitnessStore> persistableNetworkPayloadMapStorage) {
super(storageDir, persistableNetworkPayloadMapStorage);
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public String getFileName() {
return FILE_NAME;
}
@Override
public Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> getMap() {
return store.getMap();
}
@Override
public boolean canHandle(PersistableNetworkPayload payload) {
return payload instanceof SignedWitness;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected SignedWitnessStore createStore() {
return new SignedWitnessStore();
}
@Override
protected void readStore() {
super.readStore();
checkArgument(store instanceof SignedWitnessStore,
"Store is not instance of SignedWitnessStore. That can happen if the ProtoBuffer " +
"file got changed. We clear the data store and recreated it again.");
}
}

View file

@ -0,0 +1,82 @@
/*
* 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.core.account.sign;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.common.proto.persistable.PersistableEnvelope;
import com.google.protobuf.Message;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
/**
* We store only the payload in the PB file to save disc space. The hash of the payload can be created anyway and
* is only used as key in the map. So we have a hybrid data structure which is represented as list in the protobuf
* definition and provide a hashMap for the domain access.
*/
@Slf4j
public class SignedWitnessStore implements PersistableEnvelope {
@Getter
private Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> map = new ConcurrentHashMap<>();
SignedWitnessStore() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
private SignedWitnessStore(List<SignedWitness> list) {
list.forEach(item -> map.put(new P2PDataStorage.ByteArray(item.getHash()), item));
}
public Message toProtoMessage() {
return protobuf.PersistableEnvelope.newBuilder()
.setSignedWitnessStore(getBuilder())
.build();
}
private protobuf.SignedWitnessStore.Builder getBuilder() {
final List<protobuf.SignedWitness> protoList = map.values().stream()
.map(payload -> (SignedWitness) payload)
.map(SignedWitness::toProtoSignedWitness)
.collect(Collectors.toList());
return protobuf.SignedWitnessStore.newBuilder().addAllItems(protoList);
}
public static PersistableEnvelope fromProto(protobuf.SignedWitnessStore proto) {
List<SignedWitness> list = proto.getItemsList().stream()
.map(SignedWitness::fromProto).collect(Collectors.toList());
return new SignedWitnessStore(list);
}
public boolean containsKey(P2PDataStorage.ByteArray hash) {
return map.containsKey(hash);
}
}

View file

@ -15,11 +15,12 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferRestrictions;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.trade.Trade;

View file

@ -15,7 +15,7 @@
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;

View file

@ -15,10 +15,12 @@
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.core.locale.CurrencyUtil;
import bisq.core.offer.Offer;
import bisq.core.payment.AssetAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.trade.Trade;

View file

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;

View file

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;

View file

@ -17,6 +17,7 @@
package bisq.core.app;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.Alert;
import bisq.core.alert.AlertManager;
import bisq.core.alert.PrivateNotificationManager;
@ -41,7 +42,6 @@ import bisq.core.notifications.alerts.TradeEvents;
import bisq.core.notifications.alerts.market.MarketAlerts;
import bisq.core.notifications.alerts.price.PriceAlert;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.TradeLimits;
import bisq.core.provider.fee.FeeService;

View file

@ -17,10 +17,10 @@
package bisq.core.app.misc;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.app.SetupUtils;
import bisq.core.app.TorSetup;
import bisq.core.filter.FilterManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.network.crypto.EncryptionService;

View file

@ -17,6 +17,7 @@
package bisq.core.app.misc;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.app.TorSetup;
import bisq.core.dao.DaoOptionKeys;
import bisq.core.dao.DaoSetup;
@ -27,7 +28,6 @@ import bisq.core.dao.governance.myvote.MyVoteListService;
import bisq.core.dao.governance.proofofburn.MyProofOfBurnListService;
import bisq.core.dao.governance.proposal.MyProposalListService;
import bisq.core.filter.FilterManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.network.crypto.EncryptionService;

View file

@ -17,6 +17,7 @@
package bisq.core.offer;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.filter.FilterManager;
@ -24,7 +25,6 @@ import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;

View file

@ -17,6 +17,8 @@
package bisq.core.payment;
import bisq.core.account.witness.AccountAgeRestrictions;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferRestrictions;

View file

@ -17,6 +17,8 @@
package bisq.core.payment;
import bisq.core.account.witness.AccountAgeWitness;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.offer.Offer;
import java.util.Comparator;

View file

@ -17,9 +17,10 @@
package bisq.core.proto;
import bisq.core.account.sign.SignedWitness;
import bisq.core.account.witness.AccountAgeWitness;
import bisq.core.dao.governance.blindvote.storage.BlindVotePayload;
import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload;
import bisq.core.payment.AccountAgeWitness;
import bisq.core.payment.payload.AdvancedCashAccountPayload;
import bisq.core.payment.payload.AliPayAccountPayload;
import bisq.core.payment.payload.CashAppAccountPayload;
@ -166,6 +167,8 @@ public class CoreProtoResolver implements ProtoResolver {
return ProposalPayload.fromProto(proto.getProposalPayload());
case BLIND_VOTE_PAYLOAD:
return BlindVotePayload.fromProto(proto.getBlindVotePayload());
case SIGNED_WITNESS:
return SignedWitness.fromProto(proto.getSignedWitness());
default:
throw new ProtobufferRuntimeException("Unknown proto message case (PB.PersistableNetworkPayload). messageCase=" + proto.getMessageCase());
}

View file

@ -17,6 +17,8 @@
package bisq.core.proto.persistable;
import bisq.core.account.sign.SignedWitnessStore;
import bisq.core.account.witness.AccountAgeWitnessStore;
import bisq.core.arbitration.DisputeList;
import bisq.core.btc.model.AddressEntryList;
import bisq.core.btc.wallet.BtcWalletService;
@ -32,7 +34,6 @@ import bisq.core.dao.state.DaoStateStore;
import bisq.core.dao.state.model.governance.BallotList;
import bisq.core.dao.state.model.governance.MeritList;
import bisq.core.dao.state.unconfirmed.UnconfirmedBsqChangeOutputList;
import bisq.core.payment.AccountAgeWitnessStore;
import bisq.core.payment.PaymentAccountList;
import bisq.core.proto.CoreProtoResolver;
import bisq.core.trade.TradableList;
@ -136,6 +137,8 @@ public class CorePersistenceProtoResolver extends CoreProtoResolver implements P
return MyProofOfBurnList.fromProto(proto.getMyProofOfBurnList());
case UNCONFIRMED_BSQ_CHANGE_OUTPUT_LIST:
return UnconfirmedBsqChangeOutputList.fromProto(proto.getUnconfirmedBsqChangeOutputList());
case SIGNED_WITNESS_STORE:
return SignedWitnessStore.fromProto(proto.getSignedWitnessStore());
default:
throw new ProtobufferRuntimeException("Unknown proto message case(PB.PersistableEnvelope). " +

View file

@ -29,7 +29,7 @@ import lombok.extern.slf4j.Slf4j;
public class CoreNetworkCapabilities {
public static void setSupportedCapabilities(BisqEnvironment bisqEnvironment) {
Capabilities.app.addAll(Capability.TRADE_STATISTICS, Capability.TRADE_STATISTICS_2, Capability.ACCOUNT_AGE_WITNESS, Capability.ACK_MSG);
Capabilities.app.addAll(Capability.BUNDLE_OF_ENVELOPES);
Capabilities.app.addAll(Capability.BUNDLE_OF_ENVELOPES,Capability.SIGNED_ACCOUNT_AGE_WITNESS);
if (BisqEnvironment.isDaoActivated(bisqEnvironment)) {
Capabilities.app.addAll(Capability.PROPOSAL, Capability.BLIND_VOTE, Capability.BSQ_BLOCK, Capability.DAO_STATE);

View file

@ -17,6 +17,7 @@
package bisq.core.trade;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.Arbitrator;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.arbitration.Mediator;
@ -30,7 +31,6 @@ import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.proto.CoreProtoResolver;
import bisq.core.trade.protocol.ProcessModel;

View file

@ -17,6 +17,7 @@
package bisq.core.trade;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.btc.exceptions.AddressEntryException;
import bisq.core.btc.model.AddressEntry;
@ -29,7 +30,6 @@ import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.offer.availability.OfferAvailabilityModel;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager;

View file

@ -17,9 +17,11 @@
package bisq.core.trade;
import bisq.core.account.sign.SignedWitnessService;
import bisq.core.account.sign.SignedWitnessStorageService;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.account.witness.AccountAgeWitnessStorageService;
import bisq.core.app.AppOptionKeys;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AccountAgeWitnessStorageService;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager;
import bisq.core.trade.statistics.AssetTradeActivityCheck;
@ -49,8 +51,10 @@ public class TradeModule extends AppModule {
bind(ClosedTradableManager.class).in(Singleton.class);
bind(FailedTradesManager.class).in(Singleton.class);
bind(AccountAgeWitnessService.class).in(Singleton.class);
bind(ReferralIdService.class).in(Singleton.class);
bind(AccountAgeWitnessStorageService.class).in(Singleton.class);
bind(SignedWitnessService.class).in(Singleton.class);
bind(SignedWitnessStorageService.class).in(Singleton.class);
bind(ReferralIdService.class).in(Singleton.class);
bind(AssetTradeActivityCheck.class).in(Singleton.class);
bindConstant().annotatedWith(named(AppOptionKeys.DUMP_STATISTICS)).to(environment.getRequiredProperty(AppOptionKeys.DUMP_STATISTICS));
}

View file

@ -17,6 +17,7 @@
package bisq.core.trade.protocol;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.btc.model.RawTransactionInput;
import bisq.core.btc.wallet.BsqWalletService;
@ -26,7 +27,6 @@ import bisq.core.filter.FilterManager;
import bisq.core.network.MessageState;
import bisq.core.offer.Offer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.proto.CoreProtoResolver;

View file

@ -17,8 +17,8 @@
package bisq.core.trade.protocol.tasks;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.trade.Trade;
import bisq.core.trade.protocol.TradingPeer;

View file

@ -17,8 +17,8 @@
package bisq.core.trade.protocol.tasks.seller;
import bisq.core.account.witness.AccountAgeRestrictions;
import bisq.core.offer.OfferRestrictions;
import bisq.core.payment.AccountAgeRestrictions;
import bisq.core.trade.Trade;
import bisq.core.trade.protocol.tasks.TradeTask;

View file

@ -0,0 +1,243 @@
/*
* 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.core.account.sign;
import bisq.core.account.witness.AccountAgeWitness;
import bisq.core.arbitration.ArbitratorManager;
import bisq.network.p2p.storage.persistence.AppendOnlyDataStoreService;
import bisq.common.crypto.Sig;
import bisq.common.util.Utilities;
import org.bitcoinj.core.ECKey;
import com.google.common.base.Charsets;
import java.security.KeyPair;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SignedWitnessServiceTest {
private SignedWitnessService service;
@Before
public void setup() {
AppendOnlyDataStoreService appendOnlyDataStoreService = mock(AppendOnlyDataStoreService.class);
ArbitratorManager arbitratorManager = mock(ArbitratorManager.class);
when(arbitratorManager.isPublicKeyInList(any())).thenReturn(true);
service = new SignedWitnessService(null, null, null, arbitratorManager, null, appendOnlyDataStoreService);
}
@After
public void tearDown() {
}
@Test
public void testIsValidAccountAgeWitnessOk() throws Exception {
testIsValidAccountAgeWitness(false, false, false, false);
}
@Test
public void testIsValidAccountAgeWitnessArbitratorSignatureProblem() throws Exception {
testIsValidAccountAgeWitness(true, false, false, false);
}
@Test
public void testIsValidAccountAgeWitnessPeerSignatureProblem() throws Exception {
testIsValidAccountAgeWitness(false, true, false, false);
}
@Test
public void testIsValidAccountAgeWitnessDateTooSoonProblem() throws Exception {
testIsValidAccountAgeWitness(false, false, true, false);
}
@Test
public void testIsValidAccountAgeWitnessDateTooLateProblem() throws Exception {
testIsValidAccountAgeWitness(false, false, false, true);
}
private void testIsValidAccountAgeWitness(boolean signature1Problem, boolean signature2Problem, boolean date3TooSoonProblem, boolean date3TooLateProblem) throws Exception {
byte[] account1DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{1});
byte[] account2DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{2});
byte[] account3DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{3});
long account1CreationTime = getTodayMinusNDays(96);
long account2CreationTime = getTodayMinusNDays(66);
long account3CreationTime = getTodayMinusNDays(36);
AccountAgeWitness aew1 = new AccountAgeWitness(account1DataHash, account1CreationTime);
AccountAgeWitness aew2 = new AccountAgeWitness(account2DataHash, account2CreationTime);
AccountAgeWitness aew3 = new AccountAgeWitness(account3DataHash, account3CreationTime);
ECKey arbitrator1Key = new ECKey();
KeyPair peer1KeyPair = Sig.generateKeyPair();
KeyPair peer2KeyPair = Sig.generateKeyPair();
KeyPair peer3KeyPair = Sig.generateKeyPair();
String account1DataHashAsHexString = Utilities.encodeToHex(account1DataHash);
String account2DataHashAsHexString = Utilities.encodeToHex(account2DataHash);
String account3DataHashAsHexString = Utilities.encodeToHex(account3DataHash);
String signature1String = arbitrator1Key.signMessage(account1DataHashAsHexString);
byte[] signature1 = signature1String.getBytes(Charsets.UTF_8);
if (signature1Problem) {
signature1 = new byte[]{1, 2, 3};
}
byte[] signature2 = Sig.sign(peer1KeyPair.getPrivate(), account2DataHashAsHexString.getBytes(Charsets.UTF_8));
if (signature2Problem) {
signature2 = new byte[]{1, 2, 3};
}
byte[] signature3 = Sig.sign(peer2KeyPair.getPrivate(), account3DataHashAsHexString.getBytes(Charsets.UTF_8));
byte[] signer1PubKey = arbitrator1Key.getPubKey();
byte[] signer2PubKey = Sig.getPublicKeyBytes(peer1KeyPair.getPublic());
byte[] signer3PubKey = Sig.getPublicKeyBytes(peer2KeyPair.getPublic());
byte[] witnessOwner1PubKey = Sig.getPublicKeyBytes(peer1KeyPair.getPublic());
byte[] witnessOwner2PubKey = Sig.getPublicKeyBytes(peer2KeyPair.getPublic());
byte[] witnessOwner3PubKey = Sig.getPublicKeyBytes(peer3KeyPair.getPublic());
long date1 = getTodayMinusNDays(95);
long date2 = getTodayMinusNDays(64);
long date3 = getTodayMinusNDays(33);
if (date3TooSoonProblem) {
date3 = getTodayMinusNDays(63);
} else if (date3TooLateProblem) {
date3 = getTodayMinusNDays(3);
}
long tradeAmount1 = 1000;
long tradeAmount2 = 1001;
long tradeAmount3 = 1001;
SignedWitness sw1 = new SignedWitness(true, account1DataHash, signature1, signer1PubKey, witnessOwner1PubKey, date1, tradeAmount1);
SignedWitness sw2 = new SignedWitness(false, account2DataHash, signature2, signer2PubKey, witnessOwner2PubKey, date2, tradeAmount2);
SignedWitness sw3 = new SignedWitness(false, account3DataHash, signature3, signer3PubKey, witnessOwner3PubKey, date3, tradeAmount3);
service.addToMap(sw1);
service.addToMap(sw2);
service.addToMap(sw3);
Assert.assertEquals(!signature1Problem, service.isValidAccountAgeWitness(aew1));
Assert.assertEquals(!signature1Problem && !signature2Problem, service.isValidAccountAgeWitness(aew2));
Assert.assertEquals(!signature1Problem && !signature2Problem && !date3TooSoonProblem && !date3TooLateProblem, service.isValidAccountAgeWitness(aew3));
}
@Test
public void testIsValidAccountAgeWitnessEndlessLoop() throws Exception {
byte[] account1DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{1});
byte[] account2DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{2});
byte[] account3DataHash = org.bitcoinj.core.Utils.sha256hash160(new byte[]{3});
long account1CreationTime = getTodayMinusNDays(96);
long account2CreationTime = getTodayMinusNDays(66);
long account3CreationTime = getTodayMinusNDays(36);
AccountAgeWitness aew1 = new AccountAgeWitness(account1DataHash, account1CreationTime);
AccountAgeWitness aew2 = new AccountAgeWitness(account2DataHash, account2CreationTime);
AccountAgeWitness aew3 = new AccountAgeWitness(account3DataHash, account3CreationTime);
KeyPair peer1KeyPair = Sig.generateKeyPair();
KeyPair peer2KeyPair = Sig.generateKeyPair();
KeyPair peer3KeyPair = Sig.generateKeyPair();
String account1DataHashAsHexString = Utilities.encodeToHex(account1DataHash);
String account2DataHashAsHexString = Utilities.encodeToHex(account2DataHash);
String account3DataHashAsHexString = Utilities.encodeToHex(account3DataHash);
byte[] signature1 = Sig.sign(peer3KeyPair.getPrivate(), account1DataHashAsHexString.getBytes(Charsets.UTF_8));
byte[] signature2 = Sig.sign(peer1KeyPair.getPrivate(), account2DataHashAsHexString.getBytes(Charsets.UTF_8));
byte[] signature3 = Sig.sign(peer2KeyPair.getPrivate(), account3DataHashAsHexString.getBytes(Charsets.UTF_8));
byte[] signer1PubKey = Sig.getPublicKeyBytes(peer3KeyPair.getPublic());
byte[] signer2PubKey = Sig.getPublicKeyBytes(peer1KeyPair.getPublic());
byte[] signer3PubKey = Sig.getPublicKeyBytes(peer2KeyPair.getPublic());
byte[] witnessOwner1PubKey = Sig.getPublicKeyBytes(peer1KeyPair.getPublic());
byte[] witnessOwner2PubKey = Sig.getPublicKeyBytes(peer2KeyPair.getPublic());
byte[] witnessOwner3PubKey = Sig.getPublicKeyBytes(peer3KeyPair.getPublic());
long date1 = getTodayMinusNDays(95);
long date2 = getTodayMinusNDays(64);
long date3 = getTodayMinusNDays(33);
long tradeAmount1 = 1000;
long tradeAmount2 = 1001;
long tradeAmount3 = 1001;
SignedWitness sw1 = new SignedWitness(false, account1DataHash, signature1, signer1PubKey, witnessOwner1PubKey, date1, tradeAmount1);
SignedWitness sw2 = new SignedWitness(false, account2DataHash, signature2, signer2PubKey, witnessOwner2PubKey, date2, tradeAmount2);
SignedWitness sw3 = new SignedWitness(false, account3DataHash, signature3, signer3PubKey, witnessOwner3PubKey, date3, tradeAmount3);
service.addToMap(sw1);
service.addToMap(sw2);
service.addToMap(sw3);
Assert.assertFalse(service.isValidAccountAgeWitness(aew3));
}
@Test
public void testIsValidAccountAgeWitnessLongLoop() throws Exception {
AccountAgeWitness aew = null;
KeyPair signerKeyPair = Sig.generateKeyPair();
KeyPair signedKeyPair = Sig.generateKeyPair();
int iterations = 1002;
for (int i = 0; i < iterations; i++) {
byte[] accountDataHash = org.bitcoinj.core.Utils.sha256hash160(String.valueOf(i).getBytes(Charsets.UTF_8));
long accountCreationTime = getTodayMinusNDays((iterations - i) * (SignedWitnessService.CHARGEBACK_SAFETY_DAYS + 1));
aew = new AccountAgeWitness(accountDataHash, accountCreationTime);
String accountDataHashAsHexString = Utilities.encodeToHex(accountDataHash);
byte[] signature;
byte[] signerPubKey;
if (i == 0) {
// use arbitrator key
ECKey arbitratorKey = new ECKey();
signedKeyPair = Sig.generateKeyPair();
String signature1String = arbitratorKey.signMessage(accountDataHashAsHexString);
signature = signature1String.getBytes(Charsets.UTF_8);
signerPubKey = arbitratorKey.getPubKey();
} else {
signerKeyPair = signedKeyPair;
signedKeyPair = Sig.generateKeyPair();
signature = Sig.sign(signedKeyPair.getPrivate(), accountDataHashAsHexString.getBytes(Charsets.UTF_8));
signerPubKey = Sig.getPublicKeyBytes(signerKeyPair.getPublic());
}
byte[] witnessOwnerPubKey = Sig.getPublicKeyBytes(signedKeyPair.getPublic());
long date = getTodayMinusNDays((iterations - i) * (SignedWitnessService.CHARGEBACK_SAFETY_DAYS + 1));
long tradeAmount = 1000;
SignedWitness sw = new SignedWitness(i == 0, accountDataHash, signature, signerPubKey, witnessOwnerPubKey, date, tradeAmount);
service.addToMap(sw);
}
Assert.assertFalse(service.isValidAccountAgeWitness(aew));
}
private long getTodayMinusNDays(long days) {
return Instant.ofEpochMilli(new Date().getTime()).minus(days, ChronoUnit.DAYS).toEpochMilli();
}
}

View file

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.payment;
package bisq.core.account.witness;
import bisq.common.crypto.CryptoException;
import bisq.common.crypto.Sig;

View file

@ -17,6 +17,8 @@
package bisq.core.payment;
import bisq.core.account.witness.AccountAgeWitness;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.offer.Offer;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -19,11 +19,11 @@ package bisq.desktop.components;
import bisq.desktop.main.overlays.editor.PeerInfoWithTagEditor;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.Trade;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;

View file

@ -1,8 +1,8 @@
package bisq.desktop.components;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.AdvancedCashValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AdvancedCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.AdvancedCashAccountPayload;
@ -37,17 +37,15 @@ import bisq.common.util.Tuple2;
import org.apache.commons.lang3.StringUtils;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static bisq.desktop.util.FormBuilder.*;
import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField;
import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon;
import static bisq.desktop.util.FormBuilder.addTopLabelFlowPane;
@Deprecated
public class AdvancedCashForm extends PaymentMethodForm {

View file

@ -19,8 +19,8 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.util.validation.AliPayValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AliPayAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.AliPayAccountPayload;

View file

@ -23,12 +23,12 @@ import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.dao.governance.asset.AssetService;
import bisq.core.filter.FilterManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AssetAccount;
import bisq.core.payment.InstantCryptoCurrencyAccount;
import bisq.core.payment.PaymentAccount;

View file

@ -21,6 +21,7 @@ import bisq.desktop.components.InputTextField;
import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
@ -28,7 +29,6 @@ import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.BankAccountPayload;

View file

@ -22,6 +22,7 @@ import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.EmailValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
@ -29,7 +30,6 @@ import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.CashDepositAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.ChaseQuickPayValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.ChaseQuickPayAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.ChaseQuickPayAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.ClearXchangeValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.ClearXchangeAccountPayload;

View file

@ -23,6 +23,7 @@ import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.F2FValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
@ -30,7 +31,6 @@ import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.PaymentAccount;

View file

@ -23,9 +23,9 @@ import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.AccountNrValidator;
import bisq.desktop.util.validation.BranchIdValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.FasterPaymentsAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.FasterPaymentsAccountPayload;

View file

@ -3,9 +3,9 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.components.InputTextField;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.util.BSFormatter;

View file

@ -6,9 +6,9 @@ import bisq.desktop.util.validation.BankIdValidator;
import bisq.desktop.util.validation.BranchIdValidator;
import bisq.desktop.util.validation.NationalAccountIdValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.CountryBasedPaymentAccountPayload;
import bisq.core.util.BSFormatter;

View file

@ -3,11 +3,11 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.components.InputTextField;
import bisq.desktop.util.FormBuilder;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.util.BSFormatter;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.HalCashValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.HalCashAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.InteracETransferValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.InteracETransferAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.InteracETransferAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.MoneyBeamValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.MoneyBeamAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.MoneyBeamAccountPayload;

View file

@ -22,12 +22,12 @@ import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.EmailValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.MoneyGramAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.MoneyGramAccountPayload;

View file

@ -17,7 +17,7 @@
package bisq.desktop.components.paymentmethods;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.util.BSFormatter;

View file

@ -24,13 +24,13 @@ import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AssetAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.util.BSFormatter;

View file

@ -19,9 +19,9 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.util.validation.PerfectMoneyValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PerfectMoneyAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.PopmoneyValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PopmoneyAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -21,9 +21,9 @@ import bisq.desktop.components.InputTextField;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.PromptPayValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PromptPayAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.RevolutValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.RevolutAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -17,7 +17,7 @@
package bisq.desktop.components.paymentmethods;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.util.BSFormatter;

View file

@ -23,12 +23,12 @@ import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.BICValidator;
import bisq.desktop.util.validation.IBANValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.SepaAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -23,12 +23,12 @@ import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.BICValidator;
import bisq.desktop.util.validation.IBANValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.SepaInstantAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -19,8 +19,8 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.components.InputTextField;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.SpecificBanksAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.SwishValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.SwishAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.USPostalMoneyOrderValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.USPostalMoneyOrderAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -22,9 +22,9 @@ import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.UpholdValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.UpholdAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -19,8 +19,8 @@ package bisq.desktop.components.paymentmethods;
import bisq.desktop.util.validation.WeChatPayValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.WeChatPayAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -23,13 +23,13 @@ import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.EmailValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentAccountPayload;

View file

@ -34,6 +34,7 @@ import bisq.desktop.main.presentation.DaoPresentation;
import bisq.desktop.main.presentation.MarketPricePresentation;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.app.AppOptionKeys;
import bisq.core.app.BisqEnvironment;
@ -42,7 +43,6 @@ import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AliPayAccount;
import bisq.core.payment.CryptoCurrencyAccount;
import bisq.core.presentation.BalancePresentation;

View file

@ -20,11 +20,11 @@ package bisq.desktop.main.account.content.altcoinaccounts;
import bisq.desktop.common.model.ActivatableDataModel;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AssetAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.trade.TradeManager;

View file

@ -26,13 +26,13 @@ import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.dao.governance.asset.AssetService;
import bisq.core.filter.FilterManager;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountFactory;
import bisq.core.payment.payload.PaymentMethod;

View file

@ -20,12 +20,12 @@ package bisq.desktop.main.account.content.fiataccounts;
import bisq.desktop.common.model.ActivatableDataModel;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.AssetAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.trade.TradeManager;

View file

@ -69,9 +69,9 @@ import bisq.desktop.util.validation.USPostalMoneyOrderValidator;
import bisq.desktop.util.validation.UpholdValidator;
import bisq.desktop.util.validation.WeChatPayValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.app.BisqEnvironment;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CashDepositAccount;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.F2FAccount;

View file

@ -23,10 +23,10 @@ import bisq.desktop.main.overlays.windows.ContractWindow;
import bisq.desktop.main.overlays.windows.DisputeSummaryWindow;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.app.AppOptionKeys;
import bisq.core.arbitration.DisputeManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.TradeManager;
import bisq.core.util.BSFormatter;

View file

@ -35,6 +35,7 @@ import bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.app.AppOptionKeys;
import bisq.core.arbitration.Attachment;
@ -43,7 +44,6 @@ import bisq.core.arbitration.DisputeManager;
import bisq.core.arbitration.messages.DisputeCommunicationMessage;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;

View file

@ -28,13 +28,13 @@ import bisq.desktop.util.CurrencyList;
import bisq.desktop.util.CurrencyListItem;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.TradeCurrency;
import bisq.core.monetary.Price;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;

View file

@ -17,6 +17,8 @@
package bisq.desktop.main.offer;
import bisq.core.account.witness.AccountAgeRestrictions;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.Arbitrator;
import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.listeners.BalanceListener;
@ -35,8 +37,6 @@ import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeRestrictions;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;

View file

@ -23,12 +23,12 @@ package bisq.desktop.main.offer.createoffer;
import bisq.desktop.main.offer.MutableOfferDataModel;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.filter.FilterManager;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.ReferralIdService;

View file

@ -24,6 +24,7 @@ import bisq.desktop.main.settings.SettingsView;
import bisq.desktop.main.settings.preferences.PreferencesView;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.filter.FilterManager;
import bisq.core.locale.BankUtil;
import bisq.core.locale.CountryUtil;
@ -37,7 +38,6 @@ import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;
import bisq.core.payment.payload.PaymentMethod;

View file

@ -20,6 +20,8 @@ package bisq.desktop.main.offer.takeoffer;
import bisq.desktop.main.offer.OfferDataModel;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.core.account.witness.AccountAgeRestrictions;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.Arbitrator;
import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.listeners.BalanceListener;
@ -35,8 +37,6 @@ import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.AccountAgeRestrictions;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;

View file

@ -22,13 +22,13 @@ import bisq.desktop.main.MainView;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.Dispute;
import bisq.core.arbitration.DisputeManager;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.trade.Contract;

View file

@ -23,11 +23,11 @@ import bisq.desktop.main.MainView;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.util.Layout;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.DisputeManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;

View file

@ -20,9 +20,9 @@ package bisq.desktop.main.portfolio.closedtrades;
import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.offer.OpenOffer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.Tradable;
import bisq.core.trade.Trade;
import bisq.core.util.BSFormatter;

View file

@ -20,6 +20,7 @@ package bisq.desktop.main.portfolio.editoffer;
import bisq.desktop.main.offer.MutableOfferDataModel;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
@ -31,7 +32,6 @@ import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
import bisq.core.provider.fee.FeeService;

View file

@ -26,6 +26,7 @@ import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.arbitration.Dispute;
import bisq.core.arbitration.DisputeAlreadyOpenException;
import bisq.core.arbitration.DisputeManager;
@ -34,7 +35,6 @@ import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.trade.BuyerTrade;
import bisq.core.trade.SellerTrade;

View file

@ -21,10 +21,10 @@ import bisq.desktop.common.model.ActivatableWithDataModel;
import bisq.desktop.common.model.ViewModel;
import bisq.desktop.util.GUIUtil;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.Res;
import bisq.core.network.MessageState;
import bisq.core.offer.Offer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
import bisq.core.trade.closed.ClosedTradableManager;

View file

@ -22,6 +22,7 @@ import bisq.desktop.util.validation.BtcValidator;
import bisq.desktop.util.validation.FiatPriceValidator;
import bisq.desktop.util.validation.SecurityDepositValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BsqWalletService;
@ -31,7 +32,6 @@ import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.MarketPrice;

View file

@ -2,6 +2,7 @@ package bisq.desktop.main.portfolio.editoffer;
import bisq.desktop.util.validation.SecurityDepositValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
@ -11,7 +12,6 @@ import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CryptoCurrencyAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;