Merge pull request #5819 from chimp1984/fix-reorg-handling

Fix reorg handling
This commit is contained in:
Christoph Atteneder 2021-11-12 10:50:06 +01:00 committed by GitHub
commit 3e6bb3bc7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 27 deletions

View file

@ -107,15 +107,17 @@ public class FullNode extends BsqNode {
@Override
protected void startParseBlocks() {
requestChainHeadHeightAndParseBlocks(getStartBlockHeight());
}
@Override
protected void startReOrgFromLastSnapshot() {
super.startReOrgFromLastSnapshot();
int startBlockHeight = getStartBlockHeight();
rpcService.requestChainHeadHeight(chainHeight -> parseBlocksOnHeadHeight(startBlockHeight, chainHeight),
log.info("startParseBlocks: startBlockHeight={}", startBlockHeight);
rpcService.requestChainHeadHeight(chainHeight -> {
// If our persisted block is equal to the chain height we have startBlockHeight 1 block higher,
// so we do not call parseBlocksOnHeadHeight
log.info("startParseBlocks: chainHeight={}", chainHeight);
if (startBlockHeight <= chainHeight) {
parseBlocksOnHeadHeight(startBlockHeight, chainHeight);
}
},
this::handleError);
}
@ -194,12 +196,6 @@ public class FullNode extends BsqNode {
this::handleError);
}
private void requestChainHeadHeightAndParseBlocks(int startBlockHeight) {
log.info("requestChainHeadHeightAndParseBlocks with startBlockHeight={}", startBlockHeight);
rpcService.requestChainHeadHeight(chainHeight -> parseBlocksOnHeadHeight(startBlockHeight, chainHeight),
this::handleError);
}
private void parseBlocksOnHeadHeight(int startBlockHeight, int chainHeight) {
if (startBlockHeight <= chainHeight) {
blocksToParseInBatch = chainHeight - startBlockHeight;
@ -221,7 +217,9 @@ public class FullNode extends BsqNode {
log.warn("We are trying to start with a block which is above the chain height of Bitcoin Core. " +
"We need probably wait longer until Bitcoin Core has fully synced. " +
"We try again after a delay of 1 min.");
UserThread.runAfter(() -> requestChainHeadHeightAndParseBlocks(startBlockHeight), 60);
UserThread.runAfter(() -> rpcService.requestChainHeadHeight(chainHeight1 ->
parseBlocksOnHeadHeight(startBlockHeight, chainHeight1),
this::handleError), 60);
}
}

View file

@ -185,15 +185,6 @@ public class LiteNode extends BsqNode {
liteNodeNetworkService.requestBlocks(getStartBlockHeight());
}
@Override
protected void startReOrgFromLastSnapshot() {
super.startReOrgFromLastSnapshot();
int startBlockHeight = getStartBlockHeight();
liteNodeNetworkService.reset();
liteNodeNetworkService.requestBlocks(startBlockHeight);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
@ -252,7 +243,7 @@ public class LiteNode extends BsqNode {
doParseBlock(block);
runDelayedBatchProcessing(blocks, resultHandler);
} catch (RequiredReorgFromSnapshotException e) {
resultHandler.run();
log.warn("Interrupt batch processing because if a blockchain reorg. {}", e.toString());
}
});
}

View file

@ -25,9 +25,11 @@ import bisq.core.user.Cookie;
import bisq.core.user.CookieKey;
import bisq.core.user.User;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.P2PServiceListener;
import bisq.network.p2p.peers.PeerManager;
import bisq.network.p2p.seed.SeedNodeRepository;
import bisq.common.Timer;
import bisq.common.UserThread;
@ -42,6 +44,9 @@ import bisq.common.handlers.ResultHandler;
import com.google.inject.Key;
import com.google.inject.name.Names;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -108,11 +113,28 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
seedNode.setInjector(injector);
if (DevEnv.isDaoActivated()) {
injector.getInstance(DaoStateSnapshotService.class).setDaoRequiresRestartHandler(() -> gracefulShutDown(() -> {
}));
injector.getInstance(DaoStateSnapshotService.class).setDaoRequiresRestartHandler(
// We shut down with a deterministic delay per seed to avoid that all seeds shut down at the
// same time in case of a reorg. We use 30 sec. as distance delay between the seeds to be on the
// safe side. We have 12 seeds so that's 6 minutes.
() -> UserThread.runAfter(this::gracefulShutDown, 1 + (getMyIndex() * 30L))
);
}
}
private int getMyIndex() {
P2PService p2PService = injector.getInstance(P2PService.class);
SeedNodeRepository seedNodeRepository = injector.getInstance(SeedNodeRepository.class);
List<NodeAddress> seedNodes = new ArrayList<>(seedNodeRepository.getSeedNodeAddresses());
NodeAddress myAddress = p2PService.getAddress();
for (int i = 0; i < seedNodes.size(); i++) {
if (seedNodes.get(i).equals(myAddress)) {
return i;
}
}
return 0;
}
@Override
protected void startApplication() {
Cookie cookie = injector.getInstance(User.class).getCookie();
@ -197,6 +219,11 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
}
private void gracefulShutDown() {
gracefulShutDown(() -> {
});
}
@Override
public void gracefulShutDown(ResultHandler resultHandler) {
seedNode.shutDown();