Skip to content

Commit

Permalink
Merge pull request #4566 from chimp1984/fix-delayed-payout-tx-issues
Browse files Browse the repository at this point in the history
Trade protocol domain improvements
  • Loading branch information
sqrrm authored Oct 1, 2020
2 parents 0b1894a + 9fce068 commit 418361a
Show file tree
Hide file tree
Showing 153 changed files with 3,961 additions and 3,213 deletions.
4 changes: 2 additions & 2 deletions common/src/main/java/bisq/common/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public class Config {
public final List<String> bannedPriceRelayNodes;
public final List<String> bannedSeedNodes;
public final BaseCurrencyNetwork baseCurrencyNetwork;
public final NetworkParameters baseCurrencyNetworkParameters;
public final NetworkParameters networkParameters;
public final boolean ignoreLocalBtcNode;
public final String bitcoinRegtestHost;
public final boolean daoActivated;
Expand Down Expand Up @@ -702,7 +702,7 @@ public Config(String defaultAppName, File defaultUserDataDir, String... args) {
this.bannedPriceRelayNodes = options.valuesOf(bannedPriceRelayNodesOpt);
this.bannedSeedNodes = options.valuesOf(bannedSeedNodesOpt);
this.baseCurrencyNetwork = (BaseCurrencyNetwork) options.valueOf(baseCurrencyNetworkOpt);
this.baseCurrencyNetworkParameters = baseCurrencyNetwork.getParameters();
this.networkParameters = baseCurrencyNetwork.getParameters();
this.ignoreLocalBtcNode = options.valueOf(ignoreLocalBtcNodeOpt);
this.bitcoinRegtestHost = options.valueOf(bitcoinRegtestHostOpt);
this.torrcFile = options.has(torrcFileOpt) ? options.valueOf(torrcFileOpt).toFile() : null;
Expand Down
8 changes: 2 additions & 6 deletions common/src/main/java/bisq/common/proto/ProtoUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ public static byte[] byteArrayOrNullFromProto(ByteString proto) {
*/
@Nullable
public static <E extends Enum<E>> E enumFromProto(Class<E> enumType, String name) {
if (name == null) {
return null;
}

E result = Enums.getIfPresent(enumType, name).orNull();
String enumName = name != null ? name : "UNDEFINED";
E result = Enums.getIfPresent(enumType, enumName).orNull();
if (result == null) {
log.debug("Invalid value for enum " + enumType.getSimpleName() + ": " + name);
result = Enums.getIfPresent(enumType, "UNDEFINED").orNull();
log.debug("We try to lookup for an enum entry with name 'UNDEFINED' and use that if available, " +
"otherwise the enum is null. enum={}", result);
Expand Down
45 changes: 23 additions & 22 deletions core/src/main/java/bisq/core/account/sign/SignedWitnessService.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,20 +216,20 @@ public boolean publishOwnSignedWitness(SignedWitness signedWitness) {
}

// Arbitrators sign with EC key
public void signAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
ECKey key,
PublicKey peersPubKey) {
signAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey.getEncoded(), new Date().getTime());
public void signAndPublishAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
ECKey key,
PublicKey peersPubKey) {
signAndPublishAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey.getEncoded(), new Date().getTime());
}

// Arbitrators sign with EC key
public String signAccountAgeWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] peersPubKey,
long time) {
public String signAndPublishAccountAgeWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] peersPubKey,
long time) {
var witnessPubKey = peersPubKey == null ? ownerPubKey(accountAgeWitness) : peersPubKey;
return signAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, accountAgeWitness, key, witnessPubKey, time);
return signAndPublishAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, accountAgeWitness, key, witnessPubKey, time);
}

// Arbitrators sign with EC key
Expand All @@ -238,15 +238,15 @@ public String signTraderPubKey(ECKey key,
long childSignTime) {
var time = childSignTime - SIGNER_AGE - 1;
var dummyAccountAgeWitness = new AccountAgeWitness(Hash.getRipemd160hash(peersPubKey), time);
return signAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, dummyAccountAgeWitness, key, peersPubKey, time);
return signAndPublishAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, dummyAccountAgeWitness, key, peersPubKey, time);
}

// Arbitrators sign with EC key
private String signAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] peersPubKey,
long time) {
private String signAndPublishAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] peersPubKey,
long time) {
if (isSignedAccountAgeWitness(accountAgeWitness)) {
var err = "Arbitrator trying to sign already signed accountagewitness " + accountAgeWitness.toString();
log.warn(err);
Expand All @@ -272,16 +272,16 @@ private String signAccountAgeWitness(Coin tradeAmount,
return "";
}

public void selfSignAccountAgeWitness(AccountAgeWitness accountAgeWitness) throws CryptoException {
public void selfSignAndPublishAccountAgeWitness(AccountAgeWitness accountAgeWitness) throws CryptoException {
log.info("Sign own accountAgeWitness {}", accountAgeWitness);
signAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, accountAgeWitness,
signAndPublishAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, accountAgeWitness,
keyRing.getSignatureKeyPair().getPublic());
}

// Any peer can sign with DSA key
public Optional<SignedWitness> signAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
PublicKey peersPubKey) throws CryptoException {
public Optional<SignedWitness> signAndPublishAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
PublicKey peersPubKey) throws CryptoException {
if (isSignedAccountAgeWitness(accountAgeWitness)) {
log.warn("Trader trying to sign already signed accountagewitness {}", accountAgeWitness.toString());
return Optional.empty();
Expand Down Expand Up @@ -494,7 +494,8 @@ void addToMap(SignedWitness signedWitness) {
private void publishSignedWitness(SignedWitness signedWitness) {
if (!signedWitnessMap.containsKey(signedWitness.getHashAsByteArray())) {
log.info("broadcast signed witness {}", signedWitness.toString());
p2PService.addPersistableNetworkPayload(signedWitness, false);
// We set reBroadcast to true to achieve better resilience.
p2PService.addPersistableNetworkPayload(signedWitness, true);
addToMap(signedWitness);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,11 @@
import bisq.core.support.dispute.arbitration.TraderDataItem;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
import bisq.core.trade.messages.TraderSignedWitnessMessage;
import bisq.core.trade.protocol.TradingPeer;
import bisq.core.user.User;

import bisq.network.p2p.BootstrapListener;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.SendMailboxMessageListener;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.persistence.AppendOnlyDataStoreService;

Expand Down Expand Up @@ -76,7 +73,6 @@
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -202,7 +198,7 @@ public void onUpdatedDataReceived() {

private void onBootStrapped() {
republishAllFiatAccounts();
signSameNameAccounts();
signAndPublishSameNameAccounts();
}


Expand Down Expand Up @@ -271,8 +267,11 @@ private Optional<AccountAgeWitness> findWitness(Offer offer) {

private Optional<AccountAgeWitness> findTradePeerWitness(Trade trade) {
TradingPeer tradingPeer = trade.getProcessModel().getTradingPeer();
return (tradingPeer.getPaymentAccountPayload() == null || tradingPeer.getPubKeyRing() == null) ?
Optional.empty() : findWitness(tradingPeer.getPaymentAccountPayload(), tradingPeer.getPubKeyRing());
return (tradingPeer == null ||
tradingPeer.getPaymentAccountPayload() == null ||
tradingPeer.getPubKeyRing() == null) ?
Optional.empty() :
findWitness(tradingPeer.getPaymentAccountPayload(), tradingPeer.getPubKeyRing());
}

private Optional<AccountAgeWitness> getWitnessByHash(byte[] hash) {
Expand Down Expand Up @@ -562,9 +561,9 @@ boolean isDateAfterReleaseDate(long witnessDateAsLong,
}

private boolean verifyPeersCurrentDate(Date peersCurrentDate, ErrorMessageHandler errorMessageHandler) {
final boolean result = Math.abs(peersCurrentDate.getTime() - new Date().getTime()) <= TimeUnit.DAYS.toMillis(1);
boolean result = Math.abs(peersCurrentDate.getTime() - new Date().getTime()) <= TimeUnit.DAYS.toMillis(1);
if (!result) {
final String msg = "Peers current date is further than 1 day off to our current date. " +
String msg = "Peers current date is further than 1 day off to our current date. " +
"PeersCurrentDate=" + peersCurrentDate + "; myCurrentDate=" + new Date();
log.warn(msg);
errorMessageHandler.handleErrorMessage(msg);
Expand Down Expand Up @@ -643,7 +642,7 @@ public void arbitratorSignAccountAgeWitness(Coin tradeAmount,
AccountAgeWitness accountAgeWitness,
ECKey key,
PublicKey peersPubKey) {
signedWitnessService.signAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey);
signedWitnessService.signAndPublishAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey);
}

public String arbitratorSignOrphanWitness(AccountAgeWitness accountAgeWitness,
Expand All @@ -655,7 +654,7 @@ public String arbitratorSignOrphanWitness(AccountAgeWitness accountAgeWitness,
.findAny()
.orElse(null);
checkNotNull(signedWitness);
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, signedWitness.getWitnessOwnerPubKey(),
return signedWitnessService.signAndPublishAccountAgeWitness(accountAgeWitness, key, signedWitness.getWitnessOwnerPubKey(),
time);
}

Expand All @@ -669,10 +668,10 @@ public void arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] tradersPubKey,
long time) {
signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
signedWitnessService.signAndPublishAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
}

public Optional<SignedWitness> traderSignPeersAccountAgeWitness(Trade trade) {
public Optional<SignedWitness> traderSignAndPublishPeersAccountAgeWitness(Trade trade) {
AccountAgeWitness peersWitness = findTradePeerWitness(trade).orElse(null);
Coin tradeAmount = trade.getTradeAmount();
checkNotNull(trade.getProcessModel().getTradingPeer().getPubKeyRing(), "Peer must have a keyring");
Expand All @@ -682,7 +681,7 @@ public Optional<SignedWitness> traderSignPeersAccountAgeWitness(Trade trade) {
checkNotNull(peersPubKey, "Peers pub key must not be null");

try {
return signedWitnessService.signAccountAgeWitness(tradeAmount, peersWitness, peersPubKey);
return signedWitnessService.signAndPublishAccountAgeWitness(tradeAmount, peersWitness, peersPubKey);
} catch (CryptoException e) {
log.warn("Trader failed to sign witness, exception {}", e.toString());
}
Expand Down Expand Up @@ -827,7 +826,7 @@ public Set<AccountAgeWitness> getOrphanSignedWitnesses() {
.collect(Collectors.toSet());
}

public void signSameNameAccounts() {
public void signAndPublishSameNameAccounts() {
// Collect accounts that have ownerId to sign unsigned accounts with the same ownderId
var signerAccounts = Objects.requireNonNull(user.getPaymentAccounts()).stream()
.filter(account -> account.getOwnerId() != null &&
Expand All @@ -842,7 +841,7 @@ public void signSameNameAccounts() {
signerAccounts.forEach(signer -> unsignedAccounts.forEach(unsigned -> {
if (signer.getOwnerId().equals(unsigned.getOwnerId())) {
try {
signedWitnessService.selfSignAccountAgeWitness(
signedWitnessService.selfSignAndPublishAccountAgeWitness(
getMyWitness(unsigned.getPaymentAccountPayload()));
} catch (CryptoException e) {
log.warn("Self signing failed, exception {}", e.toString());
Expand All @@ -868,44 +867,4 @@ public boolean isSignWitnessTrade(Trade trade) {
!peerHasSignedWitness(trade) &&
tradeAmountIsSufficient(trade.getTradeAmount());
}

public void maybeSignWitness(Trade trade) {
if (isSignWitnessTrade(trade)) {
var signedWitnessOptional = traderSignPeersAccountAgeWitness(trade);
signedWitnessOptional.ifPresent(signedWitness -> sendSignedWitnessToPeer(signedWitness, trade));
}
}

private void sendSignedWitnessToPeer(SignedWitness signedWitness, Trade trade) {
if (trade == null) return;

NodeAddress tradingPeerNodeAddress = trade.getTradingPeerNodeAddress();
var traderSignedWitnessMessage = new TraderSignedWitnessMessage(UUID.randomUUID().toString(), trade.getId(),
tradingPeerNodeAddress, signedWitness);

p2PService.sendEncryptedMailboxMessage(
tradingPeerNodeAddress,
trade.getProcessModel().getTradingPeer().getPubKeyRing(),
traderSignedWitnessMessage,
new SendMailboxMessageListener() {
@Override
public void onArrived() {
log.info("SendMailboxMessageListener onArrived tradeId={} at peer {} SignedWitness {}",
trade.getId(), tradingPeerNodeAddress, signedWitness);
}

@Override
public void onStoredInMailbox() {
log.info("SendMailboxMessageListener onStoredInMailbox tradeId={} at peer {} SignedWitness {}",
trade.getId(), tradingPeerNodeAddress, signedWitness);
}

@Override
public void onFault(String errorMessage) {
log.error("SendMailboxMessageListener onFault tradeId={} at peer {} SignedWitness {}",
trade.getId(), tradingPeerNodeAddress, signedWitness);
}
}
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public void witnessDebugLog(Trade trade, @Nullable AccountAgeWitness myWitness)
boolean isSignWitnessTrade = accountAgeWitnessService.accountIsSigner(witness) &&
!accountAgeWitnessService.peerHasSignedWitness(trade) &&
accountAgeWitnessService.tradeAmountIsSufficient(trade.getTradeAmount());
log.info("AccountSigning: " +
log.info("AccountSigning debug log: " +
"\ntradeId: {}" +
"\nis buyer: {}" +
"\nbuyer account age witness info: {}" +
Expand Down
2 changes: 0 additions & 2 deletions core/src/main/java/bisq/core/app/BisqExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import bisq.core.setup.CorePersistedDataHost;
import bisq.core.setup.CoreSetup;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.trade.TradeManager;
import bisq.core.trade.txproof.xmr.XmrTxProofService;

import bisq.network.p2p.P2PService;
Expand Down Expand Up @@ -221,7 +220,6 @@ public void gracefulShutDown(ResultHandler resultHandler) {

try {
injector.getInstance(ArbitratorManager.class).shutDown();
injector.getInstance(TradeManager.class).shutDown();
injector.getInstance(XmrTxProofService.class).shutDown();
injector.getInstance(DaoSetup.class).shutDown();
injector.getInstance(AvoidStandbyModeService.class).shutDown();
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/java/bisq/core/app/BisqSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ private void initDomainServices() {
}, 1);
});

tradeManager.getTradableList().stream()
tradeManager.getTradesAsObservableList().stream()
.filter(trade -> trade.getOffer() != null)
.forEach(trade -> {
String details = null;
Expand All @@ -782,15 +782,13 @@ private void initDomainServices() {
rejectedTxErrorMessageHandler.accept(Res.get("popup.warning.trade.txRejected",
finalDetails, trade.getShortId(), txId));
}
tradeManager.addTradeToFailedTrades(trade);
}, 1);
}
});
}, 3);
}
});


arbitratorManager.onAllServicesInitialized();
mediatorManager.onAllServicesInitialized();
refundAgentManager.onAllServicesInitialized();
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/app/CoreModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected void configure() {

bind(File.class).annotatedWith(named(STORAGE_DIR)).toInstance(config.storageDir);

CoinFormatter btcFormatter = new ImmutableCoinFormatter(config.baseCurrencyNetworkParameters.getMonetaryFormat());
CoinFormatter btcFormatter = new ImmutableCoinFormatter(config.networkParameters.getMonetaryFormat());
bind(CoinFormatter.class).annotatedWith(named(FormattingUtils.BTC_FORMATTER_KEY)).toInstance(btcFormatter);

bind(File.class).annotatedWith(named(KEY_STORAGE_DIR)).toInstance(config.keyStorageDir);
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/bisq/core/btc/Balances.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Balances(TradeManager tradeManager,

public void onAllServicesInitialized() {
openOfferManager.getObservableList().addListener((ListChangeListener<OpenOffer>) c -> updateBalance());
tradeManager.getTradableList().addListener((ListChangeListener<Trade>) change -> updateBalance());
tradeManager.getTradesAsObservableList().addListener((ListChangeListener<Trade>) change -> updateBalance());
refundManager.getDisputesAsObservableList().addListener((ListChangeListener<Dispute>) c -> updateBalance());
btcWalletService.addBalanceListener(new BalanceListener() {
@Override
Expand All @@ -102,7 +102,7 @@ private void updateBalance() {
}

private void updateAvailableBalance() {
long sum = tradeManager.getAddressEntriesForAvailableBalanceStream()
long sum = btcWalletService.getAddressEntriesForAvailableBalanceStream()
.mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).value)
.sum();
availableBalance.set(Coin.valueOf(sum));
Expand Down
Loading

0 comments on commit 418361a

Please sign in to comment.