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

Refactor dao monitor handling #5780

Closed
wants to merge 201 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
8fbccb7
Bump version number for v1.7.5
ripcurlx Oct 19, 2021
e39ae59
Update translations for v1.7.5
ripcurlx Oct 19, 2021
48a0ebe
Add new v3 onions for wiz's bitcoin nodes
wiz Oct 19, 2021
577b07b
Move OfferPayload into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
19f813e
Move CreateOfferService into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
d98cb27
Move MarketPriceNotAvailableException into package bisq.core.offer.bi…
chimp1984 Oct 19, 2021
346fc79
Move MutableOfferPayloadFields into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
8a4c05c
Move TriggerPriceService into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
ade5d32
Move TakeOfferModel into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
20d2980
Move AvailabilityResult into package bisq.core.offer.availability
chimp1984 Oct 19, 2021
0107519
Move bisq.core.offer.messages package into package bisq.core.offer.av…
chimp1984 Oct 19, 2021
ed9f248
Move content of bisq.core.offer.placeoffer package into package bisq.…
chimp1984 Oct 19, 2021
b584fdf
Rename OfferFilter to OfferFilterService
chimp1984 Oct 19, 2021
0e23cbe
Move Contract, SellerAsMakerTrade, SellerAsTakerTrade, SellerTrade,
chimp1984 Oct 19, 2021
c0cca78
Make updateDepositTxFromWallet public
chimp1984 Oct 19, 2021
0f7cfa9
Move Trade to bisq.core.trade.model.bisq_v1 package
chimp1984 Oct 19, 2021
5944218
Move MakerTrade and TakerTrade to bisq.core.trade.model package
chimp1984 Oct 19, 2021
5a0145d
Move Tradable to bisq.core.trade.model package
chimp1984 Oct 19, 2021
81ec06d
Move TradableList to bisq.core.trade.model package
chimp1984 Oct 19, 2021
2489bbc
Make FluentProtocol.Event public
chimp1984 Oct 19, 2021
c0d1308
Make setup in FluentProtocol public
chimp1984 Oct 19, 2021
87c12fd
Move protocol classes to bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
babd70c
Move tasks package into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
5099d97
Move TradingPeer into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
a212cec
Move messages package into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
c9817ed
Move ClosedTradableManager, FailedTradesManager into bisq.core.trade.…
chimp1984 Oct 19, 2021
1b74b4e
Rename CleanupMailboxMessages to CleanupMailboxMessagesService
chimp1984 Oct 19, 2021
2141f8f
Move CleanupMailboxMessagesService, ClosedTradeUtil to package bisq.c…
chimp1984 Oct 19, 2021
f871e83
Move TransactionResultHandler, TradeResultHandler to package bisq.cor…
chimp1984 Oct 19, 2021
71c663e
Move TradeDataValidation, DumpDelayedPayoutTx, TradeDataValidation, T…
chimp1984 Oct 19, 2021
26e2676
Rename ProcessModelServiceProvider to Provider
chimp1984 Oct 19, 2021
c282b70
Rename txID to txId
chimp1984 Oct 19, 2021
30dd568
Move createoffer package inside bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
0cd0e16
Move takeoffer package inside bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
4169a87
Move MutableOffer view classes into bisq.desktop.main.offer.bisq_v1 p…
chimp1984 Oct 19, 2021
a2a7e87
Move OfferDataModel, OfferViewUtil into bisq.desktop.main.offer.bisq_…
chimp1984 Oct 19, 2021
a9f4bb7
Rename FeeUtil to OfferViewModelUtil
chimp1984 Oct 19, 2021
1e03aae
Move OfferViewModelUtil into bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
72284d7
Cleanups, refromatting, add final qualifier
chimp1984 Oct 19, 2021
71eec7b
Move TradingPeer to package bisq.core.trade.protocol.bisq_v1.model
chimp1984 Oct 19, 2021
e1efc5e
Make setPaymentStartedAckMessage and setDepositTxSentAckMessage public
chimp1984 Oct 19, 2021
760732f
Move ProcessModel to package bisq.core.trade.protocol.bisq_v1.model
chimp1984 Oct 19, 2021
94d3638
Remove m52go bitcoin node
m52go Oct 19, 2021
41d9d3f
Move OfferPayload into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
edf5c3e
Move CreateOfferService into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
4341a7e
Move MarketPriceNotAvailableException into package bisq.core.offer.bi…
chimp1984 Oct 19, 2021
042476a
Move MutableOfferPayloadFields into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
d9fd8a4
Move TriggerPriceService into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
e348000
Move TakeOfferModel into package bisq.core.offer.bisq_v1
chimp1984 Oct 19, 2021
a2d1e88
Move AvailabilityResult into package bisq.core.offer.availability
chimp1984 Oct 19, 2021
1badd69
Move bisq.core.offer.messages package into package bisq.core.offer.av…
chimp1984 Oct 19, 2021
7197b31
Move content of bisq.core.offer.placeoffer package into package bisq.…
chimp1984 Oct 19, 2021
1b4c487
Rename OfferFilter to OfferFilterService
chimp1984 Oct 19, 2021
1e9b606
Move Contract, SellerAsMakerTrade, SellerAsTakerTrade, SellerTrade,
chimp1984 Oct 19, 2021
8b21b85
Make updateDepositTxFromWallet public
chimp1984 Oct 19, 2021
d422427
Move Trade to bisq.core.trade.model.bisq_v1 package
chimp1984 Oct 19, 2021
fc3177c
Move MakerTrade and TakerTrade to bisq.core.trade.model package
chimp1984 Oct 19, 2021
58cfcff
Move Tradable to bisq.core.trade.model package
chimp1984 Oct 19, 2021
3474a2b
Move TradableList to bisq.core.trade.model package
chimp1984 Oct 19, 2021
d7b2e99
Make FluentProtocol.Event public
chimp1984 Oct 19, 2021
e3eea63
Make setup in FluentProtocol public
chimp1984 Oct 19, 2021
1b2e798
Move protocol classes to bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
508296c
Move tasks package into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
97906e0
Move TradingPeer into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
cbf2822
Move messages package into bisq.core.trade.protocol.bisq_v1 package
chimp1984 Oct 19, 2021
fd6934c
Move ClosedTradableManager, FailedTradesManager into bisq.core.trade.…
chimp1984 Oct 19, 2021
fe2871b
Rename CleanupMailboxMessages to CleanupMailboxMessagesService
chimp1984 Oct 19, 2021
e80cdf8
Move CleanupMailboxMessagesService, ClosedTradeUtil to package bisq.c…
chimp1984 Oct 19, 2021
956ffc9
Move TransactionResultHandler, TradeResultHandler to package bisq.cor…
chimp1984 Oct 19, 2021
eacf446
Move TradeDataValidation, DumpDelayedPayoutTx, TradeDataValidation, T…
chimp1984 Oct 19, 2021
e1de502
Rename ProcessModelServiceProvider to Provider
chimp1984 Oct 19, 2021
2733af9
Rename txID to txId
chimp1984 Oct 19, 2021
932c0f8
Move createoffer package inside bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
0efa0bd
Move takeoffer package inside bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
601956d
Move MutableOffer view classes into bisq.desktop.main.offer.bisq_v1 p…
chimp1984 Oct 19, 2021
9777005
Move OfferDataModel, OfferViewUtil into bisq.desktop.main.offer.bisq_…
chimp1984 Oct 19, 2021
4a9db79
Rename FeeUtil to OfferViewModelUtil
chimp1984 Oct 19, 2021
25bbad1
Move OfferViewModelUtil into bisq.desktop.main.offer.bisq_v1 package
chimp1984 Oct 19, 2021
777287a
Cleanups, refromatting, add final qualifier
chimp1984 Oct 19, 2021
401880b
Move TradingPeer to package bisq.core.trade.protocol.bisq_v1.model
chimp1984 Oct 19, 2021
afed788
Make setPaymentStartedAckMessage and setDepositTxSentAckMessage public
chimp1984 Oct 19, 2021
734d429
Move ProcessModel to package bisq.core.trade.protocol.bisq_v1.model
chimp1984 Oct 19, 2021
dca0c93
Cleanups
chimp1984 Oct 20, 2021
e752965
Add linebreak in error popup
chimp1984 Oct 20, 2021
9f3034e
Fix layout/text issues
chimp1984 Oct 20, 2021
dc82fba
Increase visibility
chimp1984 Oct 20, 2021
8768345
Remove Inject annotation at abstract classes
chimp1984 Oct 20, 2021
d1d1706
Add delegate methods to offer
chimp1984 Oct 20, 2021
dfbc746
Move Offer.Direction one level up and rename to OfferDirection
chimp1984 Oct 20, 2021
6cf0a7c
Rename paymentMethod.isAsset to paymentMethod.isBlockchain
chimp1984 Oct 20, 2021
dad19ba
Add isFiat and isAltcoin methods.
chimp1984 Oct 20, 2021
88198be
Rename availableConfirmedBalance to availableBalance
chimp1984 Oct 20, 2021
d4bb026
Only check for localhost btc node if mainnet
chimp1984 Oct 20, 2021
f8751a8
Make TxConfidenceListener and its onTransactionConfidenceChanged meth…
chimp1984 Oct 20, 2021
a927bea
Add scriptTypeId to RawTransactionInput
chimp1984 Oct 20, 2021
75072eb
Add deprecated annotation, null checks and comment to getRawInputFrom…
chimp1984 Oct 20, 2021
561ebe9
Move test classes into bisq.desktop.main.offer.bisq_v1.createoffer
chimp1984 Oct 20, 2021
8ee2554
Merge branch 'bsq-swap-low-risk-refactorings' into wip-merge2
chimp1984 Oct 20, 2021
559bc58
Fix merge issues
chimp1984 Oct 20, 2021
34c4eef
Add allowSpendMyOwnUnconfirmedTxOutputs flag to BsqCoinSelector
chimp1984 Oct 20, 2021
4757288
Add isMine method. Add error logs
chimp1984 Oct 20, 2021
0f6364d
Inline TransactionWitness
chimp1984 Oct 20, 2021
e582ffd
Add new methods
chimp1984 Oct 20, 2021
54e81d1
Add signTx and verifyNonDustTxo methods
chimp1984 Oct 20, 2021
5f8bc83
Remove unused signTx method
chimp1984 Oct 20, 2021
d95356b
Add verifiedBalance field.
chimp1984 Oct 20, 2021
cfc404b
Rename signTx to signTxAndVerifyNoDustOutputs (no code change)
chimp1984 Oct 20, 2021
82c1be1
Change log level
chimp1984 Oct 20, 2021
c15fc0c
Add comment, cleanups
chimp1984 Oct 20, 2021
d7f1b00
Rename processModel.getTradingPeer to getTradePeer
chimp1984 Oct 20, 2021
02d7dfd
Only print stack trace if dev mode
chimp1984 Oct 20, 2021
9e4be13
Change log level
chimp1984 Oct 20, 2021
8d25798
Replace Value annotation with Getter and EqualsAndHashCode
chimp1984 Oct 20, 2021
d976f11
Add methods
chimp1984 Oct 20, 2021
a3b3d56
Simplify
chimp1984 Oct 20, 2021
9d10646
Move getRandomOfferId method to OfferUtil
chimp1984 Oct 20, 2021
e061d6a
Replace Value with Getter
chimp1984 Oct 20, 2021
5b0e9ab
Rename trade.getPhase to getTradePhase
chimp1984 Oct 20, 2021
544dd89
Rename trade.getState to getTradeState
chimp1984 Oct 20, 2021
12fff54
Cleanup
chimp1984 Oct 20, 2021
2440d72
Extract methods, Cleanups
chimp1984 Oct 20, 2021
4cb0746
Extract methods, cleanups. Rename methods and vars
chimp1984 Oct 20, 2021
7211f89
Add exclude fields to EqualsAndHashCode
chimp1984 Oct 20, 2021
07883e9
Rename trade.getPhase to getTradePhase
chimp1984 Oct 20, 2021
0148a36
Extract to method in TradeUtil
chimp1984 Oct 20, 2021
1051640
Use early return. cleanup
chimp1984 Oct 20, 2021
8219bf8
Extract method. Rename vars
chimp1984 Oct 20, 2021
ee374c3
Cleanups, apply rename of getTradePhase
chimp1984 Oct 20, 2021
e940f6f
Add method. Dont return null in case of no amount but min fee
chimp1984 Oct 21, 2021
19aabba
Add method. cleanups
chimp1984 Oct 21, 2021
1c0b52c
Move OfferDirection from bisq.core.offer.bisq_v1 to bisq.core.offer
chimp1984 Oct 21, 2021
0735419
Remove handling of BundleOfEnvelopes in send method.
chimp1984 Oct 21, 2021
b80b6ec
Cleanups
chimp1984 Oct 21, 2021
23af455
Add filterPredicate
chimp1984 Oct 21, 2021
2e384ed
Make onDeleteAccount more clear
chimp1984 Oct 21, 2021
9d8c705
Only add delay if not devmode
chimp1984 Oct 21, 2021
d285157
Reduce visibility
chimp1984 Oct 21, 2021
8bb42e1
Add methods, move field up
chimp1984 Oct 21, 2021
1aa5e70
Add method
chimp1984 Oct 21, 2021
8ac40a3
Add style
chimp1984 Oct 21, 2021
c60df6e
Add linebreak (no code change)
chimp1984 Oct 21, 2021
9fb6a6c
Add isNotPublished method (will be combined later with bsq swap checks)
chimp1984 Oct 21, 2021
cfae096
Add null checks, extract variables, cleanups
chimp1984 Oct 21, 2021
2ae1860
Move tests to package bisq.desktop.main.offer.bisq_v1.createoffer
chimp1984 Oct 21, 2021
080dc3e
Merge branch 'chimp-bsq-swap' into wip-merge021.10
chimp1984 Oct 21, 2021
ab6e4e1
Dummy commit to enforce rebuild at CI
chimp1984 Oct 21, 2021
5412f8b
Merge branch 'chimp-bsq-swap' into bsq-swap-low-risk-refactorings
chimp1984 Oct 21, 2021
c920da3
Add abstract classes and interfaces. Let ProcessModel and TradingPeer…
chimp1984 Oct 21, 2021
8cd85a7
Let Trade extend TradeModel
chimp1984 Oct 21, 2021
dcd0101
Generify TradeResultHandler
chimp1984 Oct 21, 2021
5d687bd
Use TradeModel and ProtocolModel in TradeTaskRunner, TradeTask, Trade…
chimp1984 Oct 21, 2021
308bb68
Use TradeModel
chimp1984 Oct 21, 2021
453229e
Impl. onAckMessage. Add fields for concrete types
chimp1984 Oct 21, 2021
c0e70b8
Use TradeModel in trade domain
chimp1984 Oct 21, 2021
d063aff
Let OfferPayload extend OfferPayloadBase
chimp1984 Oct 21, 2021
b194960
Use TradeModel instead of Trade where appropriate.
chimp1984 Oct 21, 2021
14765d6
Move protobuf OfferPayload.Direction to OfferDirection
chimp1984 Oct 21, 2021
611b944
Move protobuf OfferPayload.Direction to OfferDirection
chimp1984 Oct 21, 2021
2f40edd
Use bitcoinj 42bbae9 (with fix required for bsq swaps)
chimp1984 Oct 21, 2021
63c385b
Add support for RemoveDataMessage in testCapability
chimp1984 Oct 21, 2021
54f17b0
Cleanups
chimp1984 Oct 21, 2021
ebfd1b5
Remove todo
chimp1984 Oct 21, 2021
9c56202
Add BSQ swap code
chimp1984 Oct 21, 2021
559491e
Merge branch 'master_upstream' into chimp-bsq-swap
chimp1984 Oct 21, 2021
cff719b
Merge branch 'chimp-bsq-swap' into bsq-swap-low-risk-refactorings
chimp1984 Oct 21, 2021
3558d01
Merge branch 'bsq-swap-low-risk-refactorings' into bsq-swap-impl
chimp1984 Oct 21, 2021
6d9d0f7
Apply codacy review suggestions
chimp1984 Oct 21, 2021
fdfb029
Move Utilities.objectToJson to JsonUtil.objectToJson
chimp1984 Oct 23, 2021
4ab1ee3
Add custom json serializer for OfferPayload
chimp1984 Oct 23, 2021
348bf3b
Update text
chimp1984 Oct 23, 2021
238a7dc
Remove missingFundsListener after successful take offer
chimp1984 Oct 23, 2021
b393968
Change log level
chimp1984 Oct 23, 2021
a77d65b
Improve BSQ swap offer details window
chimp1984 Oct 23, 2021
7dfb261
Update dev mode values for create offer
chimp1984 Oct 23, 2021
c86801f
Workaround for weird JFXComboBox bug
chimp1984 Oct 23, 2021
395d939
Add default value if no filter is available
chimp1984 Oct 23, 2021
f970f09
Add log
chimp1984 Oct 23, 2021
904fa07
Reset address entry if BSQ swap offer is used for create offer
chimp1984 Oct 23, 2021
0662fa7
Use checkNotNull and checkArgument for checking pre conditions
chimp1984 Oct 23, 2021
7c389e3
Add requestPersistence call.
chimp1984 Oct 23, 2021
ecdda10
Improve naming, comments, extract variables
chimp1984 Oct 23, 2021
b9756de
Improve naming, comments, extract variables, inline method
chimp1984 Oct 23, 2021
b92044b
Remove redundant complete call
chimp1984 Oct 23, 2021
89e7b64
Improve naming, cleanups, use static imports
chimp1984 Oct 23, 2021
d30c943
Fix linebreak
chimp1984 Oct 23, 2021
1ef21ac
Add useDaoMonitor field to PreferencesPayload
chimp1984 Oct 24, 2021
593bc34
Remove DaoEventCoordinator
chimp1984 Oct 24, 2021
35be6a1
Only call `daoStateMonitoringService.createHashFromBlock(block);`
chimp1984 Oct 24, 2021
71cc121
If dao state chain is not connecting (e.g. user had deactivated it
chimp1984 Oct 24, 2021
72184d6
Add toggle to dao monitor view to deactivate monitoring
chimp1984 Oct 24, 2021
d54d43f
Add toggle to PreferencesView
chimp1984 Oct 24, 2021
50d69e1
Fix text
chimp1984 Oct 24, 2021
85e864a
Fix text handling
chimp1984 Oct 24, 2021
463722e
Set useDaoMonitor in preferences to true for seed nodes.
chimp1984 Oct 24, 2021
b8290a7
Do not handle state hash messages if not activated
chimp1984 Oct 24, 2021
79ced07
Create snapshot after parsing done if dao monitor is deactivated
chimp1984 Oct 25, 2021
296c917
Don't check utxos during sync
chimp1984 Oct 25, 2021
5dcbb90
Move DaoStateMonitorView specific fields from
chimp1984 Oct 25, 2021
9b04889
Remove prevHash from StateHash classes.
chimp1984 Oct 25, 2021
965f526
Add isSelfConstructed to DaoStateHash (and remove it from
chimp1984 Oct 25, 2021
d97449a
Create daoStateBlocks from peers data in case we have daoMonitor deac…
chimp1984 Oct 25, 2021
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 @@ -41,7 +41,6 @@
import bisq.common.config.Config;
import bisq.common.crypto.Hash;
import bisq.common.file.FileUtil;
import bisq.common.util.GcUtil;
import bisq.common.util.Utilities;

import javax.inject.Inject;
Expand All @@ -61,12 +60,13 @@
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

/**
* Monitors the DaoState by using a hash for the complete daoState and make it accessible to the network
* so we can detect quickly if any consensus issue arise.
Expand All @@ -87,7 +87,7 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
DaoStateNetworkService.Listener<NewDaoStateHashMessage, GetDaoStateHashesRequest, DaoStateHash> {

public interface Listener {
void onChangeAfterBatchProcessing();
void onDaoStateHashesChanged();

void onCheckpointFail();
}
Expand Down Expand Up @@ -123,6 +123,9 @@ public interface Listener {

private final Preferences preferences;
private final File storageDir;
@Nullable
private Runnable createSnapshotHandler;


///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
Expand Down Expand Up @@ -175,11 +178,11 @@ public void onParseBlockChainComplete() {
daoStateNetworkService.addListeners();

// We take either the height of the previous hashBlock we have or 10 blocks below the chain tip.
int lastHeight = daoStateBlockChain.isEmpty() ?
int nextBlockHeight = daoStateBlockChain.isEmpty() ?
genesisTxInfo.getGenesisBlockHeight() :
daoStateBlockChain.getLast().getHeight() + 1;
int past10 = daoStateService.getChainHeight() - 10;
int fromHeight = Math.min(lastHeight, past10);
int fromHeight = Math.min(nextBlockHeight, past10);
daoStateNetworkService.requestHashesFromAllConnectedSeedNodes(fromHeight);

if (!ignoreDevMsg) {
Expand Down Expand Up @@ -208,8 +211,24 @@ public void onDaoStateChanged(Block block) {

@Override
public void onNewStateHashMessage(NewDaoStateHashMessage newStateHashMessage, Connection connection) {
if (newStateHashMessage.getStateHash().getHeight() <= daoStateService.getChainHeight() || !preferences.isUseDaoMonitor()) {
processPeersDaoStateHash(newStateHashMessage.getStateHash(), connection.getPeersNodeAddressOptional(), true);
// Called when receiving NewDaoStateHashMessages from peers after a new block
DaoStateHash peersDaoStateHash = newStateHashMessage.getStateHash();
if (peersDaoStateHash.getHeight() <= daoStateService.getChainHeight()) {
putInPeersMapAndCheckForConflicts(getPeersAddress(connection.getPeersNodeAddressOptional()), peersDaoStateHash);
listeners.forEach(Listener::onDaoStateHashesChanged);
}
}

@Override
public void onPeersStateHashes(List<DaoStateHash> stateHashes, Optional<NodeAddress> peersNodeAddress) {
// Called when receiving GetDaoStateHashesResponse from seed nodes
processPeersDaoStateHashes(stateHashes, peersNodeAddress);
listeners.forEach(Listener::onDaoStateHashesChanged);
if (createSnapshotHandler != null) {
createSnapshotHandler.run();
// As we get called multiple times from hashes of diff. seed nodes we want to avoid to
// call our handler multiple times.
createSnapshotHandler = null;
}
}

Expand All @@ -223,29 +242,17 @@ public void onGetStateHashRequest(Connection connection, GetDaoStateHashesReques
daoStateNetworkService.sendGetStateHashesResponse(connection, getStateHashRequest.getNonce(), daoStateHashes);
}

@Override
public void onPeersStateHashes(List<DaoStateHash> stateHashes, Optional<NodeAddress> peersNodeAddress) {
AtomicBoolean hasChanged = new AtomicBoolean(false);

stateHashes.forEach(daoStateHash -> {
boolean changed = processPeersDaoStateHash(daoStateHash, peersNodeAddress, false);
if (changed) {
hasChanged.set(true);
}
});

if (hasChanged.get()) {
listeners.forEach(Listener::onChangeAfterBatchProcessing);
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////

public void createHashFromBlock(Block block) {
updateHashChain(block);
createDaoStateBlock(block);
if (parseBlockChainComplete) {
// We notify listeners only after batch processing to avoid performance issues at UI code
listeners.forEach(Listener::onDaoStateHashesChanged);
}
}

public void requestHashesFromGenesisBlockHeight(String peersAddress) {
Expand All @@ -266,6 +273,10 @@ public void applySnapshot(LinkedList<DaoStateHash> persistedDaoStateHashChain) {
daoStateHashChain.forEach(daoStateHash -> daoStateBlockChain.add(new DaoStateBlock(daoStateHash)));
}

public void setCreateSnapshotHandler(Runnable handler) {
createSnapshotHandler = handler;
}


///////////////////////////////////////////////////////////////////////////////////////////
// Listeners
Expand All @@ -284,7 +295,7 @@ public void removeListener(Listener listener) {
// Private
///////////////////////////////////////////////////////////////////////////////////////////

private void updateHashChain(Block block) {
private void createDaoStateBlock(Block block) {
long ts = System.currentTimeMillis();
byte[] prevHash;
int height = block.getHeight();
Expand All @@ -295,20 +306,24 @@ private void updateHashChain(Block block) {
} else {
log.warn("DaoStateBlockchain is empty but we received the block which was not the genesis block. " +
"We stop execution here.");
daoStateBlockChainNotConnecting = true;
listeners.forEach(Listener::onDaoStateHashesChanged);
return;
}
} else {
if (height != daoStateBlockChain.getLast().getHeight() + 1) {
int heightOfLastBlock = daoStateBlockChain.getLast().getHeight();
if (height == heightOfLastBlock + 1) {
prevHash = daoStateBlockChain.getLast().getHash();
} else {
log.warn("New block must be 1 block above previous block. height={}, " +
"daoStateBlockChain.getLast().getHeight()={}",
height, daoStateBlockChain.getLast().getHeight());
height, heightOfLastBlock);
daoStateBlockChainNotConnecting = true;
listeners.forEach(Listener::onChangeAfterBatchProcessing);
listeners.forEach(Listener::onDaoStateHashesChanged);
return;
}

prevHash = daoStateBlockChain.getLast().getHash();
}

byte[] stateAsBytes = daoStateService.getSerializedStateForHashChain();
// We include the prev. hash in our new hash so we can be sure that if one hash is matching all the past would
// match as well.
Expand All @@ -322,9 +337,6 @@ private void updateHashChain(Block block) {

// We only broadcast after parsing of blockchain is complete
if (parseBlockChainComplete) {
// We notify listeners only after batch processing to avoid performance issues at UI code
listeners.forEach(Listener::onChangeAfterBatchProcessing);

// We delay broadcast to give peers enough time to have received the block.
// Otherwise they would ignore our data if received block is in future to their local blockchain.
int delayInSec = 5 + new Random().nextInt(10);
Expand All @@ -342,67 +354,61 @@ private void updateHashChain(Block block) {
numCalls++;
}

private boolean processPeersDaoStateHash(DaoStateHash peersDaoStateHash,
Optional<NodeAddress> peersNodeAddress,
boolean notifyListeners) {
GcUtil.maybeReleaseMemory();

AtomicBoolean changed = new AtomicBoolean(false);
AtomicBoolean inConflictWithNonSeedNode = new AtomicBoolean(this.isInConflictWithNonSeedNode);
AtomicBoolean inConflictWithSeedNode = new AtomicBoolean(this.isInConflictWithSeedNode);
StringBuilder sb = new StringBuilder();
int stateHashHeight = peersDaoStateHash.getHeight();
boolean isPeerSeedNode = peersNodeAddress.map(daoStateNetworkService::isSeedNode).orElse(false);
if (isPeerSeedNode && (daoStateBlockChain.isEmpty() || daoStateBlockChain.getLast().getHeight() == stateHashHeight - 1)) {
DaoStateHash daoStateHash = new DaoStateHash(peersDaoStateHash.getHeight(), peersDaoStateHash.getHash(), false);
DaoStateBlock daoStateBlock = new DaoStateBlock(daoStateHash);
daoStateBlock.putInPeersMap(peersNodeAddress.get().getFullAddress(), peersDaoStateHash);
daoStateBlockChain.add(daoStateBlock);
daoStateHashChain.add(daoStateHash);
changed.set(true);
} else {
daoStateBlockChain.stream()
.filter(e -> e.getHeight() == stateHashHeight).findAny()
.ifPresent(daoStateBlock -> {
String peersNodeAddressAsString = peersNodeAddress.map(NodeAddress::getFullAddress)
.orElseGet(() -> "Unknown peer " + new Random().nextInt(10000));
daoStateBlock.putInPeersMap(peersNodeAddressAsString, peersDaoStateHash);
if (!daoStateBlock.getMyStateHash().hasEqualHash(peersDaoStateHash)) {
daoStateBlock.putInConflictMap(peersNodeAddressAsString, peersDaoStateHash);
if (seedNodeAddresses.contains(peersNodeAddressAsString)) {
inConflictWithSeedNode.set(true);
} else {
inConflictWithNonSeedNode.set(true);
}
sb.append("We received a block hash from peer ")
.append(peersNodeAddressAsString)
.append(" which conflicts with our block hash.\n")
.append("my peersDaoStateHash=")
.append(daoStateBlock.getMyStateHash())
.append("\npeers peersDaoStateHash=")
.append(peersDaoStateHash);
}
changed.set(true);
});
this.isInConflictWithNonSeedNode = inConflictWithNonSeedNode.get();
this.isInConflictWithSeedNode = inConflictWithSeedNode.get();

String conflictMsg = sb.toString();
if (!conflictMsg.isEmpty()) {
if (this.isInConflictWithSeedNode)
log.warn("Conflict with seed nodes: {}", conflictMsg);
else if (this.isInConflictWithNonSeedNode)
log.debug("Conflict with non-seed nodes: {}", conflictMsg);
private void processPeersDaoStateHashes(List<DaoStateHash> stateHashes, Optional<NodeAddress> peersNodeAddress) {
stateHashes.forEach(peersHash -> {
// If we do not add own hashes during initial parsing we fill the missing hashes from the peer and create
// the at the last block our own hash.
if (!preferences.isUseDaoMonitor() &&
!findDaoStateBlock(peersHash.getHeight()).isPresent()) {
if (isLastBlock(peersHash)) {
// At the most recent block we create out own hash
daoStateService.getLastBlock().ifPresent(this::createDaoStateBlock);
} else {
// Otherwise we create a block from the peers daoStateHash
DaoStateHash daoStateHash = new DaoStateHash(peersHash.getHeight(), peersHash.getHash(), false);
DaoStateBlock daoStateBlock = new DaoStateBlock(daoStateHash);
daoStateBlockChain.add(daoStateBlock);
daoStateHashChain.add(daoStateHash);
}
}
}

if (notifyListeners && changed.get()) {
listeners.forEach(Listener::onChangeAfterBatchProcessing);
}
// In any case we add the peer to our peersMap and check for conflicts on the relevant daoStateBlock
putInPeersMapAndCheckForConflicts(getPeersAddress(peersNodeAddress), peersHash);
});
}

GcUtil.maybeReleaseMemory();
private void putInPeersMapAndCheckForConflicts(String peersAddress, DaoStateHash peersHash) {
findDaoStateBlock(peersHash.getHeight()).ifPresent(daoStateBlock -> {
daoStateBlock.putInPeersMap(peersAddress, peersHash);
checkForHashConflicts(peersHash, peersAddress, daoStateBlock);
});
}

return changed.get();
private void checkForHashConflicts(DaoStateHash peersDaoStateHash,
String peersNodeAddress,
DaoStateBlock daoStateBlock) {
if (daoStateBlock.getMyStateHash().hasEqualHash(peersDaoStateHash)) {
return;
}

daoStateBlock.putInConflictMap(peersNodeAddress, peersDaoStateHash);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("We received a block hash from peer ")
.append(peersNodeAddress)
.append(" which conflicts with our block hash.\n")
.append("my peersDaoStateHash=")
.append(daoStateBlock.getMyStateHash())
.append("\npeers peersDaoStateHash=")
.append(peersDaoStateHash);
String conflictMsg = stringBuilder.toString();

if (isSeedNode(peersNodeAddress)) {
isInConflictWithSeedNode = true;
log.warn("Conflict with seed nodes: {}", conflictMsg);
} else {
isInConflictWithNonSeedNode = true;
log.debug("Conflict with non-seed nodes: {}", conflictMsg);
}
}

private void checkUtxos(Block block) {
Expand Down Expand Up @@ -463,4 +469,25 @@ private void removeFile(String storeName) {
log.error(t.toString());
}
}

private boolean isLastBlock(DaoStateHash peersDaoStateHash) {
return daoStateService.getLastBlock()
.map(block -> block.getHeight() == peersDaoStateHash.getHeight())
.orElse(false);
}

private boolean isSeedNode(String peersNodeAddress) {
return seedNodeAddresses.contains(peersNodeAddress);
}

private String getPeersAddress(Optional<NodeAddress> peersNodeAddress) {
return peersNodeAddress.map(NodeAddress::getFullAddress)
.orElseGet(() -> "Unknown peer " + new Random().nextInt(10000));
}

private Optional<DaoStateBlock> findDaoStateBlock(int height) {
return daoStateBlockChain.stream()
.filter(myDaoStateBlock -> myDaoStateBlock.getHeight() == height)
.findFirst();
}
}
Expand Up @@ -51,4 +51,11 @@ public protobuf.DaoStateHash toProtoMessage() {
public static DaoStateHash fromProto(protobuf.DaoStateHash proto) {
return new DaoStateHash(proto.getHeight(), proto.getHash().toByteArray(), proto.getIsSelfConstructed());
}

@Override
public String toString() {
return "DaoStateHash{" +
"\r\n isSelfConstructed=" + isSelfConstructed +
"\r\n} " + super.toString();
}
}
31 changes: 21 additions & 10 deletions core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java
Expand Up @@ -128,17 +128,28 @@ public void onDaoStateChanged(Block block) {
public void onParseBlockChainComplete() {
isParseBlockChainComplete = true;

// In case we have dao monitoring deactivated we create the snapshot after we are completed with parsing.
// In case we have dao monitoring deactivated we create the snapshot after we are completed with parsing
// and we got called back from daoStateMonitoringService once the hashes are created from peers data.
if (!preferences.isUseDaoMonitor()) {
long ts = System.currentTimeMillis();
daoStateSnapshotCandidate = daoStateService.getClone();
daoStateHashChainSnapshotCandidate = new LinkedList<>(daoStateMonitoringService.getDaoStateHashChain());
daoStateStorageService.requestPersistence(daoStateSnapshotCandidate,
daoStateHashChainSnapshotCandidate,
() -> {
log.info("Persisted daoState after parsing completed at height {}. Took {} ms",
daoStateService.getChainHeight(), System.currentTimeMillis() - ts);
});
// We register a callback handler once the daoStateMonitoringService has received the missing hashes from
// the seed node and applied the latest hash. After that we are ready to make a snapshot and persist it.
daoStateMonitoringService.setCreateSnapshotHandler(() -> {
// As we did not have created any snapshots during initial parsing we create it now. We cannot use the past
// snapshot height as we have not cloned a candidate (that would cause quite some delay during parsing).
// The next snapshots will be created again according to the snapshot height grid (each 20 blocks).
// This also comes with the improvement that the user does not need to load the past blocks back to the last
// snapshot height. Thought it comes also with the small risk that in case of re-orgs the user need to do
// a resync in case the dao state would have been affected by that reorg.
long ts = System.currentTimeMillis();
daoStateSnapshotCandidate = daoStateService.getClone();
daoStateHashChainSnapshotCandidate = new LinkedList<>(daoStateMonitoringService.getDaoStateHashChain());
daoStateStorageService.requestPersistence(daoStateSnapshotCandidate,
daoStateHashChainSnapshotCandidate,
() -> {
log.info("Persisted daoState after parsing completed at height {}. Took {} ms",
daoStateService.getChainHeight(), System.currentTimeMillis() - ts);
});
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion desktop/src/main/java/bisq/desktop/main/MainView.java
Expand Up @@ -416,7 +416,7 @@ protected Tooltip computeValue() {
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void onChangeAfterBatchProcessing() {
public void onDaoStateHashesChanged() {
}

@Override
Expand Down
Expand Up @@ -133,7 +133,7 @@ protected void deactivate() {
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void onChangeAfterBatchProcessing() {
public void onDaoStateHashesChanged() {
if (daoStateService.isParseBlockChainComplete()) {
onDataUpdate();
}
Expand Down