Skip to content

Commit

Permalink
Merge pull request #260 from dashpay/bugfix-chainlocks-islocks
Browse files Browse the repository at this point in the history
fix: chainlock and islock issues and increase coinjoin look ahead
  • Loading branch information
HashEngineering authored Sep 27, 2024
2 parents f9e51ad + f902f1b commit 7ebb39d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 11 deletions.
4 changes: 3 additions & 1 deletion core/src/main/java/org/bitcoinj/core/AbstractManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,10 @@ protected void saveNow() {
/** Requests an asynchronous save on a background thread */
protected void saveLater() {
ManagerFiles files = vFileManager;
if (files != null)
if (files != null) {
Context.propagate(context);
files.saveLater();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.lang.Math.min;
Expand Down Expand Up @@ -338,6 +339,12 @@ public Masternode getMNByAddress(InetSocketAddress socketAddress) {
return null;
}

public List<Masternode> getMasternodesByVotingKey(KeyId votingKeyId) {
return mnMap.values().stream()
.filter(simplifiedMasternodeListEntry -> simplifiedMasternodeListEntry.keyIdVoting.equals(votingKeyId))
.collect(Collectors.toList());
}

public interface ForeachMNCallback {
void processMN(SimplifiedMasternodeListEntry mn);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,11 @@ public ChainLocksHandler(Context context) {
public void setBlockChain(AbstractBlockChain blockChain, AbstractBlockChain headerChain) {
this.blockChain = blockChain;
this.headerChain = headerChain;
this.blockChain.addNewBestBlockListener(this.newBestBlockListener);
this.quorumSigningManager = context.signingManager;
}

@Override
public void close() {
if (blockChain != null) {
blockChain.removeNewBestBlockListener(this.newBestBlockListener);
}
blockChain = null;
super.close();
}
Expand Down Expand Up @@ -477,8 +473,6 @@ void cleanup() {

}

private final NewBestBlockListener newBestBlockListener = block -> updatedBlockTip(block, null);

private final CopyOnWriteArrayList<ListenerRegistration<ChainLockListener>> chainLockListeners;

/**
Expand Down
29 changes: 27 additions & 2 deletions core/src/main/java/org/bitcoinj/quorums/InstantSendManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.BlockStoreException;
import org.bitcoinj.store.FullPrunedBlockStore;
import org.bitcoinj.utils.ContextPropagatingThreadFactory;
import org.bitcoinj.utils.Pair;
import org.bitcoinj.utils.Threading;
import org.slf4j.Logger;
Expand All @@ -26,6 +27,9 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class InstantSendManager implements RecoveredSignatureListener {
Expand All @@ -36,8 +40,11 @@ public class InstantSendManager implements RecoveredSignatureListener {
private static final Logger log = LoggerFactory.getLogger(InstantSendManager.class);
ReentrantLock lock = Threading.lock("InstantSendManager");
InstantSendDatabase db;
@Deprecated
Thread workThread;
@Deprecated
private boolean runWithoutThread = true;
private ScheduledExecutorService scheduledExecutorService;
AbstractBlockChain blockChain;

//Keep track of when the ISLOCK arrived
Expand All @@ -52,6 +59,11 @@ public InstantSendManager(Context context, InstantSendDatabase db) {
this.quorumSigningManager = context.signingManager;
pendingInstantSendLocks = new HashMap<>();
invalidInstantSendLocks = new HashMap<>();
scheduledExecutorService = createScheduledExecutorService();
}

private ScheduledExecutorService createScheduledExecutorService() {
return Executors.newScheduledThreadPool(1, new ContextPropagatingThreadFactory("instantsend"));
}

@Override
Expand All @@ -72,6 +84,8 @@ public void setBlockChain(AbstractBlockChain blockChain, @Nullable PeerGroup pee
peerGroup.addOnTransactionBroadcastListener(this.transactionBroadcastListener);
}
context.chainLockHandler.addChainLockListener(this.chainLockListener);
if (scheduledExecutorService == null)
scheduledExecutorService = createScheduledExecutorService();
}

public void close(PeerGroup peerGroup) {
Expand All @@ -84,6 +98,15 @@ public void close(PeerGroup peerGroup) {
peerGroup.removeOnTransactionBroadcastListener(this.transactionBroadcastListener);
}
context.chainLockHandler.removeChainLockListener(this.chainLockListener);
try {
if (!scheduledExecutorService.awaitTermination(3000, TimeUnit.MILLISECONDS)) {
log.warn("scheduled threads still remain");
}
scheduledExecutorService = null;
} catch (InterruptedException e) {
log.warn("thread termination interrupted");
// swallow
}
}

private boolean isInitialized() {
Expand Down Expand Up @@ -713,8 +736,10 @@ void processInstantSendLock(long from, Sha256Hash hash, InstantSendLock islock)
void updateWalletTransaction(Sha256Hash txid, Transaction tx) {
TransactionConfidence confidence = tx != null ? tx.getConfidence() : context.getConfidenceTable().get(txid);
if(confidence != null) {
confidence.setIXType(TransactionConfidence.IXType.IX_LOCKED);
confidence.queueListeners(TransactionConfidence.Listener.ChangeReason.IX_TYPE);
scheduledExecutorService.schedule(() -> {
confidence.setIXType(TransactionConfidence.IXType.IX_LOCKED);
confidence.queueListeners(TransactionConfidence.Listener.ChangeReason.IX_TYPE);
}, 250, TimeUnit.MILLISECONDS);
} else {
log.info("Can't find {} in mempool", txid);
}
Expand Down
14 changes: 12 additions & 2 deletions core/src/main/java/org/bitcoinj/wallet/CoinJoinExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@

public class CoinJoinExtension extends AbstractKeyChainGroupExtension {
private static final Logger log = LoggerFactory.getLogger(CoinJoinExtension.class);
private static final int COINJOIN_LOOKADHEAD = 400;
private static final int COINJOIN_LOOKADHEAD_THRESHOLD = COINJOIN_LOOKADHEAD - 1;

protected AnyKeyChainGroup coinJoinKeyChainGroup;

Expand Down Expand Up @@ -154,11 +156,19 @@ public void deserializeWalletExtension(Wallet containingWallet, byte[] data) thr
coinJoinKeyChainGroup = AnyKeyChainGroup.fromProtobufUnencrypted(containingWallet.params,
coinJoinProto.getKeyList(), ECKeyFactory.get(), false);
}
if (coinJoinKeyChainGroup.hasKeyChains()) {
setLookaheadSize();
}
rounds = coinJoinProto.getRounds();
CoinJoinClientOptions.setRounds(rounds);
loadedKeys = true;
}

private void setLookaheadSize() {
coinJoinKeyChainGroup.getActiveKeyChain().setLookaheadSize(COINJOIN_LOOKADHEAD);
coinJoinKeyChainGroup.getActiveKeyChain().setLookaheadThreshold(COINJOIN_LOOKADHEAD_THRESHOLD);
}

public boolean hasKeyChain(ImmutableList<ChildNumber> path) {
if (coinJoinKeyChainGroup == null)
return false;
Expand All @@ -179,7 +189,7 @@ public void addKeyChain(DeterministicSeed seed, ImmutableList<ChildNumber> path)
coinJoinKeyChainGroup = AnyKeyChainGroup.builder(wallet.getParams(), ECKeyFactory.get()).build();
}
coinJoinKeyChainGroup.addAndActivateHDChain(AnyDeterministicKeyChain.builder().seed(seed).accountPath(path).build());
coinJoinKeyChainGroup.getActiveKeyChain().setLookaheadSize(300);
setLookaheadSize();
}
}

Expand All @@ -196,7 +206,7 @@ public void addEncryptedKeyChain(DeterministicSeed seed, ImmutableList<ChildNumb
AnyDeterministicKeyChain chain = AnyDeterministicKeyChain.builder().seed(seed).accountPath(path).build();
AnyDeterministicKeyChain encryptedChain = chain.toEncrypted(wallet.getKeyCrypter(), keyParameter);
coinJoinKeyChainGroup.addAndActivateHDChain(encryptedChain);
coinJoinKeyChainGroup.getActiveKeyChain().setLookaheadSize(300);
setLookaheadSize();
}
}

Expand Down

0 comments on commit 7ebb39d

Please sign in to comment.