forked from Qortal/qortal
Add API call POST /peers/commonblock <connected-peer> as debugging aid
This commit is contained in:
parent
0389007491
commit
cec25ce279
@ -8,6 +8,8 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -26,10 +28,17 @@ import org.qortal.api.ApiException;
|
|||||||
import org.qortal.api.ApiExceptionFactory;
|
import org.qortal.api.ApiExceptionFactory;
|
||||||
import org.qortal.api.Security;
|
import org.qortal.api.Security;
|
||||||
import org.qortal.api.model.ConnectedPeer;
|
import org.qortal.api.model.ConnectedPeer;
|
||||||
|
import org.qortal.controller.Controller;
|
||||||
|
import org.qortal.controller.Synchronizer;
|
||||||
|
import org.qortal.controller.Synchronizer.SynchronizationResult;
|
||||||
|
import org.qortal.data.block.BlockSummaryData;
|
||||||
import org.qortal.data.network.PeerData;
|
import org.qortal.data.network.PeerData;
|
||||||
import org.qortal.network.Network;
|
import org.qortal.network.Network;
|
||||||
|
import org.qortal.network.Peer;
|
||||||
import org.qortal.network.PeerAddress;
|
import org.qortal.network.PeerAddress;
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
|
import org.qortal.repository.Repository;
|
||||||
|
import org.qortal.repository.RepositoryManager;
|
||||||
import org.qortal.utils.ExecuteProduceConsume;
|
import org.qortal.utils.ExecuteProduceConsume;
|
||||||
import org.qortal.utils.NTP;
|
import org.qortal.utils.NTP;
|
||||||
|
|
||||||
@ -260,4 +269,67 @@ public class PeersResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/commonblock")
|
||||||
|
@Operation(
|
||||||
|
summary = "Report common block with given peer.",
|
||||||
|
requestBody = @RequestBody(
|
||||||
|
required = true,
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
|
schema = @Schema(
|
||||||
|
type = "string", example = "node2.qortal.org"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "the block",
|
||||||
|
content = @Content(
|
||||||
|
array = @ArraySchema(
|
||||||
|
schema = @Schema(
|
||||||
|
implementation = BlockSummaryData.class
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiErrors({ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE})
|
||||||
|
public List<BlockSummaryData> commonBlock(String targetPeerAddress) {
|
||||||
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to resolve passed address to make things easier
|
||||||
|
PeerAddress peerAddress = PeerAddress.fromString(targetPeerAddress);
|
||||||
|
InetSocketAddress resolvedAddress = peerAddress.toSocketAddress();
|
||||||
|
|
||||||
|
List<Peer> peers = Network.getInstance().getHandshakedPeers();
|
||||||
|
Peer targetPeer = peers.stream().filter(peer -> peer.getResolvedAddress().equals(resolvedAddress)).findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (targetPeer == null)
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
int ourInitialHeight = Controller.getInstance().getChainHeight();
|
||||||
|
boolean force = true;
|
||||||
|
List<BlockSummaryData> peerBlockSummaries = new ArrayList<>();
|
||||||
|
|
||||||
|
SynchronizationResult findCommonBlockResult = Synchronizer.getInstance().fetchSummariesFromCommonBlock(repository, targetPeer, ourInitialHeight, force, peerBlockSummaries);
|
||||||
|
if (findCommonBlockResult != SynchronizationResult.OK)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return peerBlockSummaries;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
|
||||||
|
} catch (DataException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ public class Synchronizer {
|
|||||||
* @throws DataException
|
* @throws DataException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private SynchronizationResult fetchSummariesFromCommonBlock(Repository repository, Peer peer, int ourHeight, boolean force, List<BlockSummaryData> blockSummariesFromCommon) throws DataException, InterruptedException {
|
public SynchronizationResult fetchSummariesFromCommonBlock(Repository repository, Peer peer, int ourHeight, boolean force, List<BlockSummaryData> blockSummariesFromCommon) throws DataException, InterruptedException {
|
||||||
// Start by asking for a few recent block hashes as this will cover a majority of reorgs
|
// Start by asking for a few recent block hashes as this will cover a majority of reorgs
|
||||||
// Failing that, back off exponentially
|
// Failing that, back off exponentially
|
||||||
int step = INITIAL_BLOCK_STEP;
|
int step = INITIAL_BLOCK_STEP;
|
||||||
@ -320,11 +320,12 @@ public class Synchronizer {
|
|||||||
BigInteger ourChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockSig, ourBlockSummaries);
|
BigInteger ourChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockSig, ourBlockSummaries);
|
||||||
BigInteger peerChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockSig, peerBlockSummaries);
|
BigInteger peerChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockSig, peerBlockSummaries);
|
||||||
|
|
||||||
|
NumberFormat formatter = new DecimalFormat("0.###E0");
|
||||||
|
LOGGER.debug(String.format("Our chain weight: %s, peer's chain weight: %s (higher is better)", formatter.format(ourChainWeight), formatter.format(peerChainWeight)));
|
||||||
|
|
||||||
// If our blockchain has greater weight then don't synchronize with peer
|
// If our blockchain has greater weight then don't synchronize with peer
|
||||||
if (ourChainWeight.compareTo(peerChainWeight) >= 0) {
|
if (ourChainWeight.compareTo(peerChainWeight) >= 0) {
|
||||||
LOGGER.debug(String.format("Not synchronizing with peer %s as we have better blockchain", peer));
|
LOGGER.debug(String.format("Not synchronizing with peer %s as we have better blockchain", peer));
|
||||||
NumberFormat formatter = new DecimalFormat("0.###E0");
|
|
||||||
LOGGER.debug(String.format("Our chain weight: %s, peer's chain weight: %s (higher is better)", formatter.format(ourChainWeight), formatter.format(peerChainWeight)));
|
|
||||||
return SynchronizationResult.INFERIOR_CHAIN;
|
return SynchronizationResult.INFERIOR_CHAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user