use of org.ethereum.core.BlockIdentifier in project rskj by rsksmart.
the class NewBlockHashesMessageTest method test_1.
@Test
public /* NewBlockHashesMessage 1 from new */
void test_1() {
List<BlockIdentifier> identifiers = Arrays.asList(new BlockIdentifier(decode("4ee6424d776b3f59affc20bc2de59e67f36e22cc07897ff8df152242c921716b"), 1), new BlockIdentifier(decode("7d2fe4df0dbbc9011da2b3bf177f0c6b7e71a11c509035c5d751efa5cf9b4817"), 2));
NewBlockHashesMessage newBlockHashesMessage = new NewBlockHashesMessage(identifiers);
System.out.println(newBlockHashesMessage);
String expected = "f846e2a04ee6424d776b3f59affc20bc2de59e67f36e22cc07897ff8df152242c921716b01e2a07d2fe4df0dbbc9011da2b3bf177f0c6b7e71a11c509035c5d751efa5cf9b481702";
assertEquals(expected, toHexString(newBlockHashesMessage.getEncoded()));
assertEquals(EthMessageCodes.NEW_BLOCK_HASHES, newBlockHashesMessage.getCommand());
assertEquals(2, newBlockHashesMessage.getBlockIdentifiers().size());
assertEquals(null, newBlockHashesMessage.getAnswerMessage());
}
use of org.ethereum.core.BlockIdentifier in project rskj by rsksmart.
the class NewBlockHashesMessage method parse.
private void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
blockIdentifiers = new ArrayList<>();
for (int i = 0; i < paramsList.size(); ++i) {
RLPList rlpData = ((RLPList) paramsList.get(i));
blockIdentifiers.add(new BlockIdentifier(rlpData));
}
parsed = true;
}
use of org.ethereum.core.BlockIdentifier in project rskj by rsksmart.
the class NodeBlockProcessor method processSkeletonRequest.
/**
* @param sender the sender of the SkeletonRequest message.
* @param requestId the id of the request.
* @param startNumber the starting block's hash to get the skeleton.
*/
@Override
public void processSkeletonRequest(@Nonnull final MessageChannel sender, long requestId, long startNumber) {
logger.trace("Processing skeleton request {} {} from {}", requestId, startNumber, sender.getPeerNodeID());
int skeletonStep = syncConfiguration.getChunkSize();
Block blockStart = this.getBlockFromBlockchainStore(startNumber);
// If we don't have a block with the requested number, we ignore the message
if (blockStart == null) {
// Don't waste time sending an empty response.
return;
}
// We always include the skeleton block immediately before blockStart, even if it's Genesis
long skeletonStartHeight = (blockStart.getNumber() / skeletonStep) * skeletonStep;
List<BlockIdentifier> blockIdentifiers = new ArrayList<>();
long skeletonNumber = skeletonStartHeight;
int maxSkeletonChunks = syncConfiguration.getMaxSkeletonChunks();
long maxSkeletonNumber = Math.min(this.getBestBlockNumber(), skeletonStartHeight + skeletonStep * maxSkeletonChunks);
for (; skeletonNumber < maxSkeletonNumber; skeletonNumber += skeletonStep) {
byte[] skeletonHash = getSkeletonHash(skeletonNumber);
blockIdentifiers.add(new BlockIdentifier(skeletonHash, skeletonNumber));
}
// We always include the best block as part of the Skeleton response
skeletonNumber = Math.min(this.getBestBlockNumber(), skeletonNumber + skeletonStep);
byte[] skeletonHash = getSkeletonHash(skeletonNumber);
blockIdentifiers.add(new BlockIdentifier(skeletonHash, skeletonNumber));
SkeletonResponseMessage responseMessage = new SkeletonResponseMessage(requestId, blockIdentifiers);
sender.sendMessage(responseMessage);
}
use of org.ethereum.core.BlockIdentifier in project rskj by rsksmart.
the class NodeMessageHandler method relayBlock.
private void relayBlock(@Nonnull MessageChannel sender, Block block) {
final BlockNodeInformation nodeInformation = this.blockProcessor.getNodeInformation();
final Set<NodeID> nodesWithBlock = nodeInformation.getNodesByBlock(block.getHash().getBytes());
final Set<NodeID> newNodes = this.syncProcessor.getKnownPeersNodeIDs().stream().filter(p -> !nodesWithBlock.contains(p)).collect(Collectors.toSet());
List<BlockIdentifier> identifiers = new ArrayList<>();
identifiers.add(new BlockIdentifier(block.getHash().getBytes(), block.getNumber()));
channelManager.broadcastBlockHash(identifiers, newNodes);
Metrics.processBlockMessage("blockRelayed", block, sender.getPeerNodeID());
}
use of org.ethereum.core.BlockIdentifier in project rskj by rsksmart.
the class ChannelManagerImpl method broadcastBlock.
/**
* broadcastBlock Propagates a block message across active peers with exclusion of
* the peers with an id belonging to the skip set.
*
* @param block new Block to be sent
* @param skip the set of peers to avoid sending the message.
* @return a set containing the ids of the peers that received the block.
*/
@Nonnull
public Set<NodeID> broadcastBlock(@Nonnull final Block block, @Nullable final Set<NodeID> skip) {
Metrics.broadcastBlock(block);
final Set<NodeID> res = new HashSet<>();
final BlockIdentifier bi = new BlockIdentifier(block.getHash().getBytes(), block.getNumber());
final EthMessage newBlock = new RskMessage(config, new BlockMessage(block));
final EthMessage newBlockHashes = new RskMessage(config, new NewBlockHashesMessage(Arrays.asList(bi)));
synchronized (activePeers) {
// Get a randomized list with all the peers that don't have the block yet.
activePeers.values().forEach(c -> logger.trace("RSK activePeers: {}", c));
final Vector<Channel> peers = activePeers.values().stream().filter(p -> skip == null || !skip.contains(p.getNodeId())).collect(Collectors.toCollection(Vector::new));
Collections.shuffle(peers);
int sqrt = (int) Math.floor(Math.sqrt(peers.size()));
for (int i = 0; i < sqrt; i++) {
Channel peer = peers.get(i);
res.add(peer.getNodeId());
logger.trace("RSK propagate: {}", peer);
peer.sendMessage(newBlock);
}
for (int i = sqrt; i < peers.size(); i++) {
Channel peer = peers.get(i);
logger.trace("RSK announce: {}", peer);
peer.sendMessage(newBlockHashes);
}
}
return res;
}
Aggregations