Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ jobs:
fail-fast: false
name: JAVA ${{ matrix.distribution }} ${{ matrix.java }} OS ${{ matrix.os }} Gradle ${{ matrix.gradle }}
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up JDK
uses: actions/setup-java@v1
uses: actions/setup-java@v4
Comment thread
HashEngineering marked this conversation as resolved.
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
- name: Build bls library
run: |
git submodule update --init --recursive
cd contrib/dashj-bls
git apply catch_changes.patch
mvn package -DskipTests -Dmaven.javadoc.skip=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ public void close() {
if (masternodeGroup != null) {
masternodeGroup.removePreMessageReceivedEventListener(preMessageReceivedEventListener);
}
// Ensure executor is shut down

// Shut down the executor before nulling fields — queued tasks may still reference them.
ExecutorService execToStop = null;
lock.lock();
try {
Expand All @@ -310,6 +311,8 @@ public void close() {
if (execToStop != null) {
execToStop.shutdown();
}
blockChain = null;
peerGroup = null;
}

public boolean isMasternodeOrDisconnectRequested(MasternodeAddress address) {
Expand Down Expand Up @@ -547,12 +550,12 @@ public void processTransaction(Transaction tx) {
if(!alreadyHave(item)) {
getdata.addItem(item);
} else {
log.info("coinjoin: DSQUEUE: already has {}", item.hash);
log.debug("coinjoin: DSQUEUE: already has {}", item.hash);
}
}
if (!getdata.getItems().isEmpty()) {
// This will cause us to receive a bunch of block or tx messages.
log.info(COINJOIN_EXTRA, "coinjoin: DSQUEUE: requesting {} dsq messages", getdata.getItems().size());
log.debug(COINJOIN_EXTRA, "coinjoin: DSQUEUE: requesting {} dsq messages", getdata.getItems().size());
getdata.getItems().forEach(
inventoryItem -> log.info(COINJOIN_EXTRA, "getdata: {}", inventoryItem.hash));
peer.sendMessage(getdata);
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/org/bitcoinj/core/AbstractManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ public void setFilename(String filename) {
autosaveToFile(new File(filename), DELAY_TIME, TimeUnit.MILLISECONDS, null);
}

/**
* Typically called when DashSystem is shutting down.
*/
public void close() {
if (vFileManager != null) {
shutdownAutosaveAndWait();
Expand Down
54 changes: 54 additions & 0 deletions core/src/main/java/org/bitcoinj/core/DualBlockChain.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

package org.bitcoinj.core;

import org.bitcoinj.core.listeners.DownloadProgressTracker;
import org.bitcoinj.store.BlockStoreException;
import org.bitcoinj.utils.Threading;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -105,4 +107,56 @@ public StoredBlock getBlock(int height) {
public StoredBlock getChainHead() {
return getLongestChain().chainHead;
}

PeerGroup peerGroup;
MyDownloadProgressTracker downloadProgressTracker;

private static class MyDownloadProgressTracker extends DownloadProgressTracker {
volatile boolean headerDownloadCompleted = false;
volatile boolean blockDownloadCompleted = false;
MyDownloadProgressTracker(boolean preprocessingBeforeBlocks) {
super(preprocessingBeforeBlocks);
}

@Override
public void doneHeaderDownload() {
super.doneHeaderDownload();
headerDownloadCompleted = true;
}

@Override
protected void doneDownload() {
super.doneDownload();
blockDownloadCompleted = true;
}
}

public void setPeerGroup(PeerGroup peerGroup, MasternodeSync masternodeSync) {
close();
if (peerGroup != null) {
this.peerGroup = peerGroup;
downloadProgressTracker = new MyDownloadProgressTracker(masternodeSync.hasSyncFlag(MasternodeSync.SYNC_FLAGS.SYNC_BLOCKS_AFTER_PREPROCESSING));
peerGroup.addHeadersDownloadedEventListener(Threading.USER_THREAD, downloadProgressTracker);
peerGroup.addHeadersDownloadStartedEventListener(Threading.USER_THREAD, downloadProgressTracker);
peerGroup.addBlocksDownloadedEventListener(Threading.USER_THREAD, downloadProgressTracker);
peerGroup.addChainDownloadStartedEventListener(Threading.USER_THREAD, downloadProgressTracker);
peerGroup.addMasternodeListDownloadListener(Threading.USER_THREAD, downloadProgressTracker);
}
}

public boolean isInitialHeaderSyncComplete() {
return downloadProgressTracker != null && (downloadProgressTracker.headerDownloadCompleted || downloadProgressTracker.blockDownloadCompleted);
}

public void close() {
if (peerGroup != null && downloadProgressTracker != null) {
peerGroup.removeHeadersDownloadedEventListener(downloadProgressTracker);
peerGroup.removeHeadersDownloadStartedEventListener(downloadProgressTracker);
peerGroup.removeBlocksDownloadedEventListener(downloadProgressTracker);
peerGroup.removeChainDownloadStartedEventListener(downloadProgressTracker);
peerGroup.removeMasternodeListDownloadedListener(downloadProgressTracker);
}
peerGroup = null;
downloadProgressTracker = null;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
2 changes: 2 additions & 0 deletions core/src/main/java/org/bitcoinj/core/MasternodeSync.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ public void close() {
if (peerGroup != null) {
peerGroup.removePreMessageReceivedEventListener(preMessageReceivedEventListener);
}
peerGroup = null;
blockChain = null;
}

public MasternodeSync(Context context, boolean isLiteMode, boolean allowInstantSendInLiteMode) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/bitcoinj/core/PeerGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -2044,7 +2044,7 @@ protected void handlePeerDeath(final Peer peer, @Nullable Throwable exception) {
final Peer newDownloadPeer = selectDownloadPeer(peers);
if (newDownloadPeer != null) {
setDownloadPeer(newDownloadPeer);
if (downloadListener != null) {
if (downloadListener != null && vRunning) {
startBlockChainDownloadFromPeer(newDownloadPeer);
}
}
Expand Down
9 changes: 8 additions & 1 deletion core/src/main/java/org/bitcoinj/core/SporkManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ private static void makeSporkDefinition(SporkId sporkId, long defaultValue) {
@GuardedBy("lock") private final HashMap<SporkId, Long> mapSporksCachedValues;
@GuardedBy("lock") private final HashSet<KeyId> setSporkPubKeyIds = new HashSet<>();

private PeerGroup peerGroup;
private AbstractBlockChain blockChain;
private MasternodeSync masternodeSync;
private final Context context;
Expand All @@ -91,6 +92,7 @@ public SporkManager(Context context)
public void setBlockChain(AbstractBlockChain blockChain, @Nullable PeerGroup peerGroup, MasternodeSync masternodeSync) {
this.blockChain = blockChain;
this.masternodeSync = masternodeSync;
this.peerGroup = peerGroup;
if (peerGroup != null) {
peerGroup.addConnectedEventListener(peerConnectedEventListener);
peerGroup.addPreMessageReceivedEventListener(SAME_THREAD, preMessageReceivedEventListener);
Expand All @@ -102,18 +104,23 @@ public void clear() {
mapSporksByHash.clear();
}

public void close(PeerGroup peerGroup) {
public void close() {
if (peerGroup != null) {
peerGroup.removeConnectedEventListener(peerConnectedEventListener);
peerGroup.removePreMessageReceivedEventListener(preMessageReceivedEventListener);
}
peerGroup = null;
blockChain = null;
masternodeSync = null;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

void processSpork(Peer from, SporkMessage spork) {
// if (context.isLiteMode() && !context.allowInstantXinLiteMode()) {
// return; //disable all darksend/masternode related functionality
// }

if (blockChain == null) return; // closed during shutdown

Sha256Hash hash = spork.getHash();
String logMessage = String.format("SPORK -- hash: %s id: %d (%s) value: %10d bestHeight: %d peer=%s:%d",
hash, spork.getSporkId().value, String.format("%1$35s", spork.getSporkId().name()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ public void removeEventListeners(AbstractBlockChain blockChain, PeerGroup peerGr
blockChain.removeNewBestBlockListener(newBestBlockListener);
blockChain.removeReorganizeListener(reorganizeListener);
}
if (peerGroup != null) {
if (peerGroup != null) {
peerGroup.removeConnectedEventListener(peerConnectedEventListener);
peerGroup.removeChainDownloadStartedEventListener(chainDownloadStartedEventListener);
peerGroup.removeHeadersDownloadStartedEventListener(headersDownloadStartedEventListener);
Expand Down Expand Up @@ -597,6 +597,7 @@ public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
public final PeerConnectedEventListener peerConnectedEventListener = new PeerConnectedEventListener() {
@Override
public void onPeerConnected(Peer peer, int peerCount) {
if (peerGroup == null) return; // closed during shutdown
downloadPeer = peerGroup.getDownloadPeer();
log.info("peer connected and setting download peer to {} with onPeerConnected", downloadPeer);
}
Expand All @@ -605,6 +606,7 @@ public void onPeerConnected(Peer peer, int peerCount) {
final PeerDisconnectedEventListener peerDisconnectedEventListener = new PeerDisconnectedEventListener() {
@Override
public void onPeerDisconnected(Peer peer, int peerCount) {
if (peerGroup == null) return; // closed during shutdown
if (downloadPeer == peer) {
downloadPeer = peerGroup.getDownloadPeer();
log.info("setting download peer to {} with onPeerDisconnected, previously was {}", downloadPeer, peer);
Expand Down Expand Up @@ -897,5 +899,7 @@ public void close() {
retryFuture.cancel(true);
retryFuture = null;
}
peerGroup = null;
blockChain = null;
}
}
13 changes: 10 additions & 3 deletions core/src/main/java/org/bitcoinj/evolution/QuorumRotationState.java
Original file line number Diff line number Diff line change
Expand Up @@ -445,13 +445,20 @@ public boolean isSynced() {
if (blockChain != null && !params.isDIP0024Active(blockChain.getBestChainHeight()))
return true;

if(mnListAtH.getHeight() == -1)
if (mnListAtH.getHeight() == -1)
return false;

if (peerGroup == null)
if (blockChain == null)
return false;

int mostCommonHeight = peerGroup.getMostCommonHeight();
if (!blockChain.isInitialHeaderSyncComplete()) {
return false;
}

// Use local chain height instead of peerGroup.getMostCommonHeight() to avoid
// acquiring the PeerGroup lock, which can deadlock during shutdown or when the
// PeerGroup thread holds it while blocked on SPVBlockStore I/O.
int mostCommonHeight = blockChain.getBestChainHeight();

// determine when the last QR height was
LLMQParameters llmqParameters = params.getLlmqs().get(llmqType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,9 @@ public void close() {
threadPool.shutdownNow(); // Send interrupt signal but don't wait
}
saveNow(); // Always save, regardless of thread pool state
peerGroup = null;
blockChain = null;
super.close();
Comment thread
HashEngineering marked this conversation as resolved.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1719,5 +1719,6 @@ public void close() {
peerGroup.removeGetDataEventListener(getDataEventListener);
peerGroup.removePreMessageReceivedEventListener(preMessageReceivedEventListener);
}
peerGroup = null;
}
}
11 changes: 9 additions & 2 deletions core/src/main/java/org/bitcoinj/manager/DashSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class DashSystem {
public AbstractBlockChain blockChain;
@Nullable
public AbstractBlockChain headerChain;
DualBlockChain dualBlockChain;
public SporkManager sporkManager;
public MasternodePayments masternodePayments;
public MasternodeSync masternodeSync;
Expand Down Expand Up @@ -251,10 +252,13 @@ private void stopLLMQThread() {
}
}

/**
* close down DashSystem and free resources, typically called after the PeerGroup is shutdown
*/
public void close() {
if (initializedObjects) {
log.info("Closing network spork configuration manager");
sporkManager.close(peerGroup);
sporkManager.close();
log.info("Closing masternode synchronization state");
masternodeSync.close();
log.info("Closing masternode list manager (includes thread pool shutdown)");
Expand Down Expand Up @@ -285,6 +289,8 @@ public void close() {
log.info("Closing header chain");
headerChain.close();
}
log.info("closing dual blockchain");
dualBlockChain.close();
log.info("Clearing peer group reference");
peerGroup = null;
}
Expand All @@ -295,13 +301,14 @@ public void setPeerGroupAndBlockChain(PeerGroup peerGroup, AbstractBlockChain bl
this.peerGroup = peerGroup;
this.blockChain = blockChain;
this.headerChain = headerChain;
DualBlockChain dualBlockChain = new DualBlockChain(headerChain, blockChain);
dualBlockChain = new DualBlockChain(headerChain, blockChain);
hashStore = new HashStore(blockChain.getBlockStore());
blockChain.addNewBestBlockListener(newBestBlockListener);
handleActivations(blockChain.getChainHead());
if (initializedObjects) {
sporkManager.setBlockChain(blockChain, peerGroup, masternodeSync);
masternodeSync.setBlockChain(blockChain, peerGroup, netFullfilledRequestManager, governanceManager);
dualBlockChain.setPeerGroup(peerGroup, masternodeSync);
masternodeListManager.setBlockChain(
dualBlockChain,
peerGroup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ public void processChainLockSignature(Peer peer, ChainLockSignature clsig)
processNewChainLock(peer, clsig, hash);
}

void processNewChainLock(Peer from, ChainLockSignature clsig, Sha256Hash hash)
{
void processNewChainLock(Peer from, ChainLockSignature clsig, Sha256Hash hash) {
if (blockChain == null) return; // closed during shutdown
Comment thread
HashEngineering marked this conversation as resolved.

lock.lock();
try {
if (blockChain == null) return; // re-check under lock
if (seenChainLocks.put(hash, Utils.currentTimeMillis()) != null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ public void close(PeerGroup peerGroup) {
if (chainLocksHandler != null) {
chainLocksHandler.removeChainLockListener(this.chainLockListener);
}
blockChain = null;
peerGroup = null;
chainLocksHandler = null;
wallets.forEach(wallet -> wallet.removeCoinsSentEventListener(coinsSentEventListener));
try {
if (!scheduledExecutorService.awaitTermination(3000, TimeUnit.MILLISECONDS)) {
Expand Down
Loading
Loading