mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Add domain layer for signed account age witnesses (credits ManfredKarrer and oscarguindzberg)
This commit is contained in:
parent
4b235dbadb
commit
fdf5364c47
83 changed files with 998 additions and 83 deletions
|
@ -33,5 +33,6 @@ public enum Capability {
|
|||
ACK_MSG,
|
||||
BSQ_BLOCK,
|
||||
DAO_STATE,
|
||||
BUNDLE_OF_ENVELOPES
|
||||
BUNDLE_OF_ENVELOPES,
|
||||
SIGNED_ACCOUNT_AGE_WITNESS
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
169
core/src/main/java/bisq/core/account/sign/SignedWitness.java
Normal file
169
core/src/main/java/bisq/core/account/sign/SignedWitness.java
Normal 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}";
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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). " +
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue