Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v1.4.0 and v1.4.1 #4655

Merged
merged 143 commits into from Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
5294820
Bump version number for v1.4.0
ripcurlx Oct 8, 2020
2d06946
Update translations for v1.4.0
ripcurlx Oct 8, 2020
f13a7b1
Create a P2WPKH keychain for new btc wallets
oscarguindzberg Sep 14, 2020
cd28660
Add a P2WPKH keychain for existing wallets
oscarguindzberg Sep 14, 2020
ced357c
AddressEntry: Add boolean segwit flag
oscarguindzberg Sep 14, 2020
e85c66b
Stop using LegacyAddress for btc addresses
oscarguindzberg Sep 14, 2020
0c7f345
Fix log msg in BtcCoinSelector
oscarguindzberg Sep 14, 2020
0f4c66f
Comment out segwit BSQ account path
oscarguindzberg Sep 29, 2020
2551571
TradeWalletService: adapt to segwit wallet
oscarguindzberg Sep 29, 2020
d8b7557
WalletService: adapt to segwit wallet
oscarguindzberg Sep 29, 2020
a370848
New AddressEntry: use different script types
oscarguindzberg Sep 25, 2020
a9cc28f
AddressEntryList: arbitrator entry use P2PKH
oscarguindzberg Sep 25, 2020
f9f5d92
Add segwit/legacy checbox for address creation
oscarguindzberg Sep 25, 2020
1f3c585
Serialize tx without segwit
oscarguindzberg Sep 28, 2020
58afc00
Don't create an extra address at startup
oscarguindzberg Sep 28, 2020
e2f74f0
Don't create a wallet address when not needed
oscarguindzberg Sep 28, 2020
d1aeedd
Remove unused WalletService.findKeyFromPubKeyHash()
oscarguindzberg Sep 24, 2020
78a2a43
Remove unused import
oscarguindzberg Sep 14, 2020
01455d2
Enable reusing unused AVAILABLE entries
oscarguindzberg Oct 1, 2020
4a2c0ad
Make codacy happy
oscarguindzberg Oct 1, 2020
86ddd06
Validate AddressEntry.segwit
oscarguindzberg Oct 5, 2020
b9e404f
Make it clear segwit is not used for the trade protocol yet.
oscarguindzberg Oct 5, 2020
5524ba3
BtcWalletService.getFreshAddressEntry(): code clean up
oscarguindzberg Oct 5, 2020
d1aaf3e
Construct dummy outputs with LegacyAddress
oscarguindzberg Oct 5, 2020
3554e19
setWitness(): Code clean up
oscarguindzberg Oct 5, 2020
499d7b7
Use try-with-resources
oscarguindzberg Oct 5, 2020
1d82c01
Improve error handling for P2WPKH
oscarguindzberg Oct 5, 2020
694446c
Switch back to LegacyAddress for fee estimation
oscarguindzberg Oct 5, 2020
a747e83
Fix add segwit keychain for encrypted wallet
oscarguindzberg Oct 7, 2020
417daf5
Use bitcoinj 0.15.8 (commit a733034)
oscarguindzberg Oct 8, 2020
87da2ae
Do a backup of the wallet before segwit migration
oscarguindzberg Oct 8, 2020
261e0ec
Check migratedWalletToSegwit is true
oscarguindzberg Oct 8, 2020
35e0c34
Merge pull request #4568 from oscarguindzberg/segwitWallet
sqrrm Oct 8, 2020
9404e8f
Add NO_ADDRESS_PRE_FIX capability.
chimp1984 Oct 7, 2020
e73a4b4
Cleanups
chimp1984 Oct 7, 2020
6f7dfcf
Make onRemoved default in interface
chimp1984 Oct 7, 2020
40f9cfb
Add methods for getting peers capabilities
chimp1984 Oct 7, 2020
8aec306
Remove verification for address prefix
chimp1984 Oct 7, 2020
9821dd6
Clear capabilitiesListeners at shutdown
chimp1984 Oct 7, 2020
17974f3
Refactor: move SupportedCapabilitiesMessage handling code out to a me…
chimp1984 Oct 7, 2020
1c07be0
Use only node address for equals and hashcode
chimp1984 Oct 7, 2020
bf659a1
Pass supportedCapabilities to PeerManager. Not further processed yet,…
chimp1984 Oct 7, 2020
2523c2e
Use getSingleThreadListeningExecutor, cleanups
chimp1984 Oct 7, 2020
765f9ea
Apply code inspection suggestions
chimp1984 Oct 7, 2020
186a9d6
Add findPeersCapabilities method
chimp1984 Oct 7, 2020
7af16d7
Add getDateAsLong method, add setter for capabilities
chimp1984 Oct 7, 2020
25bfe2d
Add findPeersCapabilities method
chimp1984 Oct 7, 2020
2552675
Replace persistedPeers with peerList
chimp1984 Oct 7, 2020
bf674ea
Use getPersistedPeers for peerList.getList() calls
chimp1984 Oct 7, 2020
cf06930
Update common/src/main/java/bisq/common/app/Capability.java
chimp1984 Oct 7, 2020
983f610
Update p2p/src/main/java/bisq/network/p2p/network/Connection.java
chimp1984 Oct 7, 2020
31e7e26
Fix incorrect handling of decryptedEntries size
chimp1984 Oct 7, 2020
4575516
Refactor: Return early
chimp1984 Oct 7, 2020
ed960ab
Refactor: Rearrange code, remove unused methods, renamings (no functi…
chimp1984 Oct 7, 2020
0686079
Refactor: Rename method
chimp1984 Oct 7, 2020
31ce5cc
Use connection.getPeersNodeAddressOptional().isPresent() instead of c…
chimp1984 Oct 7, 2020
cfda0af
Fix tests
chimp1984 Oct 8, 2020
351db88
Use a hashset instead of list to avoid duplicates. Filter out my own …
chimp1984 Oct 8, 2020
2fd0104
Decrease failedConnectionAttempts onConnection
chimp1984 Oct 8, 2020
f36a173
Fix incorrect collection used in == 1 check
chimp1984 Oct 8, 2020
b748bff
Add isPresent check
chimp1984 Oct 8, 2020
c7f23e8
Do not log size as we don't want to call potentially expensive toProt…
chimp1984 Oct 8, 2020
f53290b
Copy peers in a new hashset to avoid concurrent modification exc at s…
chimp1984 Oct 8, 2020
447235c
Dont reassign param
chimp1984 Oct 8, 2020
c88bc1c
Use custom class MailboxItem instead of Tuple
chimp1984 Oct 8, 2020
c8feef1
Apply code review suggestions
chimp1984 Oct 8, 2020
4f685f8
When updating the capability from a reported peer we check if the rep…
chimp1984 Oct 8, 2020
6e3fdbc
Apply codacy suggestions
chimp1984 Oct 8, 2020
00bed02
Add TradeStatistics3 and related classes
chimp1984 Oct 5, 2020
406bcfb
Remove PublishTradeStatistics from buyer protocol
chimp1984 Oct 5, 2020
b75aa67
Refactor: Move class
chimp1984 Oct 5, 2020
a522d0a
Refactor: Rename class
chimp1984 Oct 5, 2020
b2665bd
let seller publish trade statistics only if peer is updated user. If …
chimp1984 Oct 5, 2020
6d43c09
Delete TradeStatistics (version 1)
chimp1984 Oct 5, 2020
9820751
We "hack" TradeStatistics2StorageService to fulfill our needs:
chimp1984 Oct 5, 2020
c4a4c87
Apply TradeStatistics3 to TradeStatisticsManager and some related cla…
chimp1984 Oct 5, 2020
52be126
Apply TradeStatistics3 to client classes
chimp1984 Oct 5, 2020
0e70a99
Adjust tests, remove tests which do not make sense anymore
chimp1984 Oct 5, 2020
6766835
Use TradeStatistics3 in protobuf file
chimp1984 Oct 5, 2020
b14266d
Remove resource file
chimp1984 Oct 5, 2020
9016cb6
Prune mediator and refund agent entries for all entries beside the la…
chimp1984 Oct 6, 2020
f56fe42
Add injector.getInstance(TradeStatisticsConverter.class) to BisqExecu…
chimp1984 Oct 6, 2020
fa374b9
Do conversion in a thread to not block UI thread. takes about 4 secon…
chimp1984 Oct 6, 2020
213050c
Add filter for excluding null objects
chimp1984 Oct 6, 2020
17f4ae2
Add check that size is > LOOK_BACK_RANGE
chimp1984 Oct 6, 2020
e95ab2a
Add resource file for 1.4.0 (should be updated at release time)
chimp1984 Oct 6, 2020
58d2f1b
Apply codacy suggestions
chimp1984 Oct 8, 2020
197d8c1
Remove copy&past mistake
chimp1984 Oct 8, 2020
18a27e9
Republish trade statistics from seller side if peer capability is kno…
chimp1984 Oct 8, 2020
68a10cf
Remove comment line
chimp1984 Oct 8, 2020
66740b7
Remove unused variable
chimp1984 Oct 9, 2020
39c8ade
Cleanups: Remove outdated TODOs, fix typos
chimp1984 Oct 9, 2020
352d954
Merge pull request #4610 from chimp1984/remove-address-prefix
ripcurlx Oct 9, 2020
3687a03
Merge pull request #4611 from chimp1984/new-trade-statistics
ripcurlx Oct 9, 2020
4d2f1b5
Set memo to tx after tx creation and not on broadcast success, as bro…
chimp1984 Oct 11, 2020
db10aa3
Only show xmr auto conf label for sell offers
chimp1984 Oct 11, 2020
1f0590d
Use hash at conversion also for local data to avoid duplicates.
chimp1984 Oct 11, 2020
8e93e4b
Use aesKey in Wallet.toString()
oscarguindzberg Oct 11, 2020
2dc7662
Merge pull request #4627 from oscarguindzberg/fixWalletToString
ripcurlx Oct 12, 2020
1eb730a
Merge pull request #4626 from chimp1984/avoid-duplicate-trade-stats
ripcurlx Oct 12, 2020
ee14884
Merge pull request #4625 from chimp1984/only-showXmrAutoConf-for-sell…
ripcurlx Oct 12, 2020
41b2e6a
Merge pull request #4619 from chimp1984/fix-memo-bug-issue-4616
ripcurlx Oct 12, 2020
1c0655e
Stop PeerGroup only if running
oscarguindzberg Oct 12, 2020
0d46906
Change write json files to disk strategy
chimp1984 Oct 13, 2020
88f9eee
Merge pull request #4635 from chimp1984/fix-performance-issues-at-dum…
ripcurlx Oct 13, 2020
e5dd316
Merge pull request #4631 from oscarguindzberg/fixPeerGroupStop
ripcurlx Oct 13, 2020
3b4d109
Fix bug at mediation with old client
chimp1984 Oct 13, 2020
129eaa7
Merge pull request #4638 from chimp1984/fix-mediation-bug
sqrrm Oct 13, 2020
b719302
Exclude depositTxId as it seems that leads to
chimp1984 Oct 13, 2020
30c77aa
Update resource file.
chimp1984 Oct 13, 2020
be08c86
Merge pull request #4640 from chimp1984/update-trade-stat-resource-file
sqrrm Oct 13, 2020
8647007
Accept segwit addresses when sending non-BSQ funds
oscarguindzberg Oct 12, 2020
e30a7e0
Merge pull request #4632 from oscarguindzberg/fixSendNonBsq
ripcurlx Oct 13, 2020
cc5bdfa
Change data response behaviour
chimp1984 Oct 14, 2020
b0bc3d0
Remove lombok getter for date and rename getDate to getDateAsLong and…
chimp1984 Oct 14, 2020
5f9d3d1
Add GetInventory messages
chimp1984 Oct 14, 2020
32b953b
Improve GetInventoryRequester and GetInventoryRequestManager
chimp1984 Oct 14, 2020
8ed83ca
Merge pull request #4642 from chimp1984/change-handling-of-trade-stat…
sqrrm Oct 14, 2020
c41bfd7
Merge pull request #4643 from chimp1984/add-get-inventory-msg
sqrrm Oct 14, 2020
866b227
Replace emzy's v2 seednodes with new v3 seednodes
wiz Oct 14, 2020
58f5066
Resolve conflict in 'core/src/main/resources/btc_mainnet.seednodes'.
mrosseel Oct 14, 2020
feb4e52
Use toString for NullPointerException
chimp1984 Oct 14, 2020
fc87524
Add dont show again check box to validation exception popups
chimp1984 Oct 14, 2020
fe3828e
Dont include dead transactions in check for unconfirmed txs chain
chimp1984 Oct 14, 2020
8b404e1
Exclude time-locked txs at isUnconfirmedTransactionsLimitHit
chimp1984 Oct 15, 2020
9946496
Merge pull request #4647 from chimp1984/persist-seen-mediator-warnings
ripcurlx Oct 15, 2020
4f26544
Merge pull request #4648 from chimp1984/dont-include-dead-txs-in-limi…
ripcurlx Oct 15, 2020
b7c6c42
Update bitcoinj checkpoints for v1.4.0
ripcurlx Oct 14, 2020
c08a9bd
Only remove offer locally when necessary
ripcurlx Oct 15, 2020
101c172
Merge pull request #4651 from ripcurlx/keep-offer-when-canceling
sqrrm Oct 15, 2020
4e2e523
Update data stores for v1.4.0
ripcurlx Oct 15, 2020
10b05aa
Revert jdk.module.illegalAccess=deny
ripcurlx Oct 15, 2020
bac1e7b
Revert to SNAPSHOT version
ripcurlx Oct 16, 2020
3e17058
Move segwit checkbox
oscarguindzberg Oct 16, 2020
6b4d77f
Handle Capabilities for encrypted messages (offer availibility reques…
chimp1984 Oct 16, 2020
0b38fcc
Add file name to temp file at write to disk
chimp1984 Oct 16, 2020
8cb6a05
Fix min height for trade statistics table
chimp1984 Oct 16, 2020
294b45d
Republish trade statistics if not found in existing trade stats.
chimp1984 Oct 16, 2020
b924107
Merge pull request #4659 from chimp1984/fix-missing-capability-handli…
sqrrm Oct 16, 2020
0dea954
Merge pull request #4662 from chimp1984/fix-republish-trade-stats
sqrrm Oct 16, 2020
b5d16bc
Merge pull request #4658 from oscarguindzberg/moveSegwitCheckbox
ripcurlx Oct 17, 2020
7ae6e84
Bump version number for v1.4.1
ripcurlx Oct 18, 2020
b1fb571
Revert to SNAPSHOT version
ripcurlx Oct 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -305,7 +305,7 @@ public void writeToDisk(protobuf.PersistableEnvelope serialized, @Nullable Runna

tempFile = usedTempFilePath != null
? FileUtil.createNewFile(usedTempFilePath)
: File.createTempFile("temp", null, dir);
: File.createTempFile("temp_" + fileName, null, dir);
// Don't use a new temp file path each time, as that causes the delete-on-exit hook to leak memory:
tempFile.deleteOnExit();

Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/bisq/core/trade/TradeManager.java
Expand Up @@ -40,6 +40,7 @@
import bisq.core.trade.protocol.TakerProtocol;
import bisq.core.trade.protocol.TradeProtocol;
import bisq.core.trade.protocol.TradeProtocolFactory;
import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.User;
import bisq.core.util.Validator;
Expand All @@ -49,6 +50,7 @@
import bisq.network.p2p.DecryptedMessageWithPubKey;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.network.TorNetworkNode;

import bisq.common.ClockWatcher;
import bisq.common.config.Config;
Expand Down Expand Up @@ -83,6 +85,7 @@

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -133,6 +136,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
private ErrorMessageHandler takeOfferRequestErrorMessageHandler;
@Getter
private final LongProperty numPendingTrades = new SimpleLongProperty();
private final ReferralIdService referralIdService;
private final DumpDelayedPayoutTx dumpDelayedPayoutTx;
@Getter
private final boolean allowFaultyDelayedTxs;
Expand All @@ -158,6 +162,7 @@ public TradeManager(User user,
ProcessModelServiceProvider processModelServiceProvider,
ClockWatcher clockWatcher,
PersistenceManager<TradableList<Trade>> persistenceManager,
ReferralIdService referralIdService,
DumpDelayedPayoutTx dumpDelayedPayoutTx,
@Named(Config.ALLOW_FAULTY_DELAYED_TXS) boolean allowFaultyDelayedTxs) {
this.user = user;
Expand All @@ -174,6 +179,7 @@ public TradeManager(User user,
this.mediatorManager = mediatorManager;
this.processModelServiceProvider = processModelServiceProvider;
this.clockWatcher = clockWatcher;
this.referralIdService = referralIdService;
this.dumpDelayedPayoutTx = dumpDelayedPayoutTx;
this.allowFaultyDelayedTxs = allowFaultyDelayedTxs;
this.persistenceManager = persistenceManager;
Expand Down Expand Up @@ -324,6 +330,13 @@ public TradeProtocol getTradeProtocol(Trade trade) {
private void initPersistedTrades() {
tradableList.forEach(this::initPersistedTrade);
persistedTradesInitialized.set(true);

// We do not include failed trades as they should not be counted anyway in the trade statistics
Set<Trade> allTrades = new HashSet<>(closedTradableManager.getClosedTrades());
allTrades.addAll(tradableList.getList());
String referralId = referralIdService.getOptionalReferralId().orElse(null);
boolean isTorNetworkNode = p2PService.getNetworkNode() instanceof TorNetworkNode;
tradeStatisticsManager.maybeRepublishTradeStatistics(allTrades, referralId, isTorNetworkNode);
}

private void initPersistedTrade(Trade trade) {
Expand Down
26 changes: 1 addition & 25 deletions core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java
Expand Up @@ -39,10 +39,6 @@

import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler;
import bisq.common.util.Utilities;

import java.util.Date;
import java.util.GregorianCalendar;

import lombok.extern.slf4j.Slf4j;

Expand All @@ -57,27 +53,6 @@ public SellerProtocol(SellerTrade trade) {
super(trade);
}

@Override
protected void onInitialized() {
super.onInitialized();

// We get called the constructor with any possible state and phase. As we don't want to log an error for such
// cases we use the alternative 'given' method instead of 'expect'.

// We only re-publish for about 2 weeks after 1.4.0 release until most nodes have updated to
// achieve sufficient resilience.
boolean currentDateBeforeCutOffDate = new Date().before(Utilities.getUTCDate(2020, GregorianCalendar.NOVEMBER, 1));
given(anyPhase(Trade.Phase.DEPOSIT_PUBLISHED,
Trade.Phase.DEPOSIT_CONFIRMED,
Trade.Phase.FIAT_SENT,
Trade.Phase.FIAT_RECEIVED,
Trade.Phase.PAYOUT_PUBLISHED)
.with(SellerEvent.STARTUP)
.preCondition(currentDateBeforeCutOffDate))
.setup(tasks(SellerPublishesTradeStatistics.class))
.executeTasks();
}


///////////////////////////////////////////////////////////////////////////////////////////
// Mailbox
Expand All @@ -92,6 +67,7 @@ public void onMailboxMessage(TradeMessage message, NodeAddress peerNodeAddress)
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// Incoming messages
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Expand Up @@ -17,22 +17,15 @@

package bisq.core.trade.protocol.tasks.seller;

import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.trade.Trade;
import bisq.core.trade.protocol.tasks.TradeTask;
import bisq.core.trade.statistics.TradeStatistics3;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.network.NetworkNode;
import bisq.network.p2p.network.TorNetworkNode;

import bisq.common.app.Capability;
import bisq.common.taskrunner.TaskRunner;

import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import static com.google.common.base.Preconditions.checkNotNull;
Expand All @@ -56,34 +49,9 @@ protected void run() {
// Our peer has updated, so as we are the seller we will publish the trade statistics.
// The peer as buyer does not publish anymore with v.1.4.0 (where Capability.TRADE_STATISTICS_3 was added)

Map<String, String> extraDataMap = new HashMap<>();
if (processModel.getReferralIdService().getOptionalReferralId().isPresent()) {
extraDataMap.put(OfferPayload.REFERRAL_ID, processModel.getReferralIdService().getOptionalReferralId().get());
}

NodeAddress mediatorNodeAddress = checkNotNull(trade.getMediatorNodeAddress());
// The first 4 chars are sufficient to identify a mediator.
// For testing with regtest/localhost we use the full address as its localhost and would result in
// same values for multiple mediators.
NetworkNode networkNode = model.getProcessModel().getP2PService().getNetworkNode();
String truncatedMediatorNodeAddress = networkNode instanceof TorNetworkNode ?
mediatorNodeAddress.getFullAddress().substring(0, 4) :
mediatorNodeAddress.getFullAddress();

NodeAddress refundAgentNodeAddress = checkNotNull(trade.getRefundAgentNodeAddress());
String truncatedRefundAgentNodeAddress = networkNode instanceof TorNetworkNode ?
refundAgentNodeAddress.getFullAddress().substring(0, 4) :
refundAgentNodeAddress.getFullAddress();

Offer offer = checkNotNull(trade.getOffer());
TradeStatistics3 tradeStatistics = new TradeStatistics3(offer.getCurrencyCode(),
trade.getTradePrice().getValue(),
trade.getTradeAmountAsLong(),
offer.getPaymentMethod().getId(),
trade.getTakeOfferDate().getTime(),
truncatedMediatorNodeAddress,
truncatedRefundAgentNodeAddress,
extraDataMap);
String referralId = processModel.getReferralIdService().getOptionalReferralId().orElse(null);
boolean isTorNetworkNode = model.getProcessModel().getP2PService().getNetworkNode() instanceof TorNetworkNode;
TradeStatistics3 tradeStatistics = TradeStatistics3.from(trade, referralId, isTorNetworkNode);
if (tradeStatistics.isValid()) {
log.info("Publishing trade statistics");
processModel.getP2PService().addPersistableNetworkPayload(tradeStatistics, true);
Expand Down
Expand Up @@ -21,9 +21,12 @@
import bisq.core.monetary.AltcoinExchangeRate;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.trade.Trade;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.network.p2p.storage.payload.ProcessOncePersistableNetworkPayload;
Expand All @@ -46,6 +49,7 @@
import com.google.common.base.Charsets;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

Expand All @@ -67,6 +71,36 @@
public final class TradeStatistics2 implements ProcessOncePersistableNetworkPayload, PersistableNetworkPayload,
CapabilityRequiringPayload, Comparable<TradeStatistics2> {

public static TradeStatistics2 from(Trade trade,
@Nullable String referralId,
boolean isTorNetworkNode) {
Map<String, String> extraDataMap = new HashMap<>();
if (referralId != null) {
extraDataMap.put(OfferPayload.REFERRAL_ID, referralId);
}

NodeAddress mediatorNodeAddress = trade.getMediatorNodeAddress();
if (mediatorNodeAddress != null) {
// The first 4 chars are sufficient to identify a mediator.
// For testing with regtest/localhost we use the full address as its localhost and would result in
// same values for multiple mediators.
String address = isTorNetworkNode ?
mediatorNodeAddress.getFullAddress().substring(0, 4) :
mediatorNodeAddress.getFullAddress();
extraDataMap.put(TradeStatistics2.MEDIATOR_ADDRESS, address);
}

Offer offer = trade.getOffer();
checkNotNull(offer, "offer must not ne null");
checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not ne null");
return new TradeStatistics2(offer.getOfferPayload(),
trade.getTradePrice(),
trade.getTradeAmount(),
trade.getDate(),
trade.getDepositTxId(),
extraDataMap);
}

@SuppressWarnings("SpellCheckingInspection")
public static final String MEDIATOR_ADDRESS = "medAddr";
@SuppressWarnings("SpellCheckingInspection")
Expand Down
Expand Up @@ -21,8 +21,12 @@
import bisq.core.monetary.AltcoinExchangeRate;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.trade.Trade;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.storage.payload.CapabilityRequiringPayload;
import bisq.network.p2p.storage.payload.DateSortedTruncatablePayload;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
Expand All @@ -48,6 +52,7 @@

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

Expand All @@ -66,6 +71,43 @@
public final class TradeStatistics3 implements ProcessOncePersistableNetworkPayload, PersistableNetworkPayload,
CapabilityRequiringPayload, DateSortedTruncatablePayload {


public static TradeStatistics3 from(Trade trade,
@Nullable String referralId,
boolean isTorNetworkNode) {
Map<String, String> extraDataMap = new HashMap<>();
if (referralId != null) {
extraDataMap.put(OfferPayload.REFERRAL_ID, referralId);
}

NodeAddress mediatorNodeAddress = checkNotNull(trade.getMediatorNodeAddress());
// The first 4 chars are sufficient to identify a mediator.
// For testing with regtest/localhost we use the full address as its localhost and would result in
// same values for multiple mediators.
String truncatedMediatorNodeAddress = isTorNetworkNode ?
mediatorNodeAddress.getFullAddress().substring(0, 4) :
mediatorNodeAddress.getFullAddress();

// RefundAgentNodeAddress can be null if converted from old version.
String truncatedRefundAgentNodeAddress = null;
NodeAddress refundAgentNodeAddress = trade.getRefundAgentNodeAddress();
if (refundAgentNodeAddress != null) {
truncatedRefundAgentNodeAddress = isTorNetworkNode ?
refundAgentNodeAddress.getFullAddress().substring(0, 4) :
refundAgentNodeAddress.getFullAddress();
}

Offer offer = checkNotNull(trade.getOffer());
return new TradeStatistics3(offer.getCurrencyCode(),
trade.getTradePrice().getValue(),
trade.getTradeAmountAsLong(),
offer.getPaymentMethod().getId(),
trade.getTakeOfferDate().getTime(),
truncatedMediatorNodeAddress,
truncatedRefundAgentNodeAddress,
extraDataMap);
}

// This enum must not change the order as we use the ordinal for storage to reduce data size.
// The payment method string can be quite long and would consume 15% more space.
// When we get a new payment method we can add it to the enum at the end. Old users would add it as string if not
Expand Down
Expand Up @@ -21,8 +21,11 @@
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.BuyerTrade;
import bisq.core.trade.Trade;

import bisq.network.p2p.P2PService;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.persistence.AppendOnlyDataStoreService;

import bisq.common.config.Config;
Expand All @@ -46,6 +49,8 @@

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

@Singleton
@Slf4j
public class TradeStatisticsManager {
Expand Down Expand Up @@ -140,4 +145,48 @@ private void maybeDumpStatistics() {
list.toArray(array);
jsonFileManager.writeToDiscThreaded(Utilities.objectToJson(array), "trade_statistics");
}

public void maybeRepublishTradeStatistics(Set<Trade> trades,
@Nullable String referralId,
boolean isTorNetworkNode) {
long ts = System.currentTimeMillis();
Set<P2PDataStorage.ByteArray> hashes = tradeStatistics3StorageService.getMapOfAllData().keySet();
trades.forEach(trade -> {
if (trade instanceof BuyerTrade) {
log.debug("Trade: {} is a buyer trade, we only republish we have been seller.",
trade.getShortId());
return;
}

TradeStatistics3 tradeStatistics3 = TradeStatistics3.from(trade, referralId, isTorNetworkNode);
boolean hasTradeStatistics3 = hashes.contains(new P2PDataStorage.ByteArray(tradeStatistics3.getHash()));
if (hasTradeStatistics3) {
log.debug("Trade: {}. We have already a tradeStatistics matching the hash of tradeStatistics3.",
trade.getShortId());
return;
}

// If we did not find a TradeStatistics3 we look up if we find a TradeStatistics3 converted from
// TradeStatistics2 where we used the original hash, which is not the native hash of the
// TradeStatistics3 but of TradeStatistics2.
TradeStatistics2 tradeStatistics2 = TradeStatistics2.from(trade, referralId, isTorNetworkNode);
boolean hasTradeStatistics2 = hashes.contains(new P2PDataStorage.ByteArray(tradeStatistics2.getHash()));
if (hasTradeStatistics2) {
log.debug("Trade: {}. We have already a tradeStatistics matching the hash of tradeStatistics2. ",
trade.getShortId());
return;
}

if (!tradeStatistics3.isValid()) {
log.warn("Trade: {}. Trade statistics is invalid. We do not publish it.", tradeStatistics3);
return;
}

log.info("Trade: {}. We republish tradeStatistics3 as we did not find it in the existing trade statistics. ",
trade.getShortId());
p2PService.addPersistableNetworkPayload(tradeStatistics3, true);
});
log.info("maybeRepublishTradeStatistics took {} ms. Number of tradeStatistics: {}. Number of own trades: {}",
System.currentTimeMillis() - ts, hashes.size(), trades.size());
}
}
Expand Up @@ -544,7 +544,7 @@ private ToggleButton getToggleButton(String label, TradesChartsViewModel.TickUni

private void createTable() {
tableView = new TableView<>();
tableView.setMinHeight(120);
tableView.setMinHeight(80);
tableView.setPrefHeight(130);
VBox.setVgrow(tableView, Priority.ALWAYS);

Expand Down