Merge pull request #6451 from HenrikJannsen/avoid_sending_repeated_block_related_report_data

Avoid sending repeated block related report data
This commit is contained in:
Alejandro García 2022-12-11 17:38:00 +02:00 committed by GitHub
commit 6c7764fc33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 43 deletions

View file

@ -89,9 +89,14 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
DaoStateNetworkService.Listener<NewDaoStateHashMessage, GetDaoStateHashesRequest, DaoStateHash> {
public interface Listener {
void onDaoStateHashesChanged();
default void onDaoStateHashesChanged() {
}
void onCheckpointFail();
default void onCheckpointFail() {
}
default void onDaoStateBlockCreated() {
}
}
private final DaoStateService daoStateService;
@ -347,7 +352,7 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
// We only broadcast after parsing of blockchain is complete
if (parseBlockChainComplete) {
// 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.
// Otherwise, they would ignore our data if received block is in future to their local blockchain.
int delayInSec = 5 + new Random().nextInt(10);
if (Config.baseCurrencyNetwork().isRegtest()) {
delayInSec = 1;
@ -361,6 +366,7 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
duration);
accumulatedDuration += duration;
numCalls++;
listeners.forEach(Listener::onDaoStateBlockCreated);
return Optional.of(daoStateBlock);
}
@ -371,15 +377,14 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
// If we do not add own hashes during initial parsing we fill the missing hashes from the peer and create
// at the last block our own hash.
int height = peersHash.getHeight();
if (!useDaoMonitor &&
!findDaoStateBlock(height).isPresent()) {
if (!useDaoMonitor && findDaoStateBlock(height).isEmpty()) {
if (daoStateService.getChainHeight() == height) {
// At the most recent block we create our own hash
optionalDaoStateBlock = daoStateService.getLastBlock()
.map(this::createDaoStateBlock)
.orElse(findDaoStateBlock(height));
} else {
// Otherwise we create a block from the peers daoStateHash
// Otherwise, we create a block from the peers daoStateHash
DaoStateHash daoStateHash = new DaoStateHash(height, peersHash.getHash(), false);
DaoStateBlock daoStateBlock = new DaoStateBlock(daoStateHash);
daoStateBlockChain.add(daoStateBlock);

View file

@ -95,10 +95,9 @@ public class SeedNodeReportingService {
private final String seedNodeReportingServerUrl;
private final DaoStateListener daoStateListener;
private final HttpClient httpClient;
private Timer dataReportTimer;
private final Timer heartBeatTimer;
private final ExecutorService executor;
private final Timer heartBeatTimer;
private Timer dataReportTimer;
@Inject
public SeedNodeReportingService(P2PService p2PService,
@ -128,28 +127,22 @@ public class SeedNodeReportingService {
heartBeatTimer = UserThread.runPeriodically(this::sendHeartBeat, HEART_BEAT_DELAY_SEC);
// We send each time when a new block is received and the DAO hash has been provided (which
// takes a bit after the block arrives).
daoStateMonitoringService.addListener(new DaoStateMonitoringService.Listener() {
@Override
public void onDaoStateHashesChanged() {
sendBlockRelatedData();
}
@Override
public void onCheckpointFail() {
}
});
// Independent of the block
daoStateListener = new DaoStateListener() {
@Override
public void onParseBlockChainComplete() {
daoFacade.removeBsqStateListener(daoStateListener);
dataReportTimer = UserThread.runPeriodically(() -> sendDataReport(), REPORT_DELAY_SEC);
sendDataReport();
sendBlockRelatedData();
// We send each time when a new block is received and the DAO hash has been provided (which
// takes a bit after the block arrives).
daoStateMonitoringService.addListener(new DaoStateMonitoringService.Listener() {
@Override
public void onDaoStateBlockCreated() {
sendBlockRelatedData();
}
});
}
};
daoFacade.addBsqStateListener(daoStateListener);
@ -252,26 +245,30 @@ public class SeedNodeReportingService {
}
private void sendReportingItems(ReportingItems reportingItems) {
CompletableFuture.runAsync(() -> {
log.info("Send report to monitor server: {}", reportingItems.toString());
// We send the data as hex encoded protobuf data. We do not use the envelope as it is not part of the p2p system.
byte[] protoMessageAsBytes = reportingItems.toProtoMessageAsBytes();
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(seedNodeReportingServerUrl))
.POST(HttpRequest.BodyPublishers.ofByteArray(protoMessageAsBytes))
.header("User-Agent", getMyAddress())
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
log.error("Response error message: {}", response);
try {
CompletableFuture.runAsync(() -> {
log.info("Send report to monitor server: {}", reportingItems.toString());
// We send the data as hex encoded protobuf data. We do not use the envelope as it is not part of the p2p system.
byte[] protoMessageAsBytes = reportingItems.toProtoMessageAsBytes();
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(seedNodeReportingServerUrl))
.POST(HttpRequest.BodyPublishers.ofByteArray(protoMessageAsBytes))
.header("User-Agent", getMyAddress())
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
log.error("Response error message: {}", response);
}
} catch (IOException e) {
log.warn("IOException at sending reporting. {}", e.getMessage());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} catch (IOException e) {
log.warn("IOException at sending reporting. {}", e.getMessage());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, executor);
}, executor);
} catch (Throwable t) {
log.error("Did not send reportingItems {} because of exception {}", reportingItems, t.toString());
}
}
private String getMyAddress() {