use of co.rsk.net.eth.RskMessage 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;
}
use of co.rsk.net.eth.RskMessage in project rskj by rsksmart.
the class ChannelManagerImpl method broadcastBlockHash.
@Nonnull
public Set<NodeID> broadcastBlockHash(@Nonnull final List<BlockIdentifier> identifiers, @Nullable final Set<NodeID> targets) {
final Set<NodeID> res = new HashSet<>();
final EthMessage newBlockHash = new RskMessage(config, new NewBlockHashesMessage(identifiers));
synchronized (activePeers) {
activePeers.values().forEach(c -> logger.trace("RSK activePeers: {}", c));
activePeers.values().stream().filter(p -> targets == null || targets.contains(p.getNodeId())).forEach(peer -> {
logger.trace("RSK announce hash: {}", peer);
peer.sendMessage(newBlockHash);
});
}
return res;
}
use of co.rsk.net.eth.RskMessage in project rskj by rsksmart.
the class ChannelManagerImpl method broadcastTransaction.
/**
* broadcastTransaction Propagates a transaction message across active peers with exclusion of
* the peers with an id belonging to the skip set.
*
* @param transaction new Transaction 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 transaction.
*/
@Nonnull
public Set<NodeID> broadcastTransaction(@Nonnull final Transaction transaction, @Nullable final Set<NodeID> skip) {
Metrics.broadcastTransaction(transaction);
List<Transaction> transactions = new ArrayList<>();
transactions.add(transaction);
final Set<NodeID> res = new HashSet<>();
final EthMessage newTransactions = new RskMessage(config, new TransactionsMessage(transactions));
synchronized (activePeers) {
final Vector<Channel> peers = activePeers.values().stream().filter(p -> skip == null || !skip.contains(p.getNodeId())).collect(Collectors.toCollection(Vector::new));
for (Channel peer : peers) {
res.add(peer.getNodeId());
peer.sendMessage(newTransactions);
}
}
return res;
}
use of co.rsk.net.eth.RskMessage in project rskj by rsksmart.
the class ChannelManagerImpl method sendMessageTo.
@Override
public boolean sendMessageTo(NodeID nodeID, MessageWithId message) {
synchronized (activePeers) {
EthMessage msg = new RskMessage(config, message);
Channel channel = activePeers.get(nodeID);
if (channel == null) {
return false;
}
channel.sendMessage(msg);
}
return true;
}
use of co.rsk.net.eth.RskMessage in project rskj by rsksmart.
the class ChannelManagerImpl method broadcastStatus.
@Override
public int broadcastStatus(Status status) {
final EthMessage message = new RskMessage(config, new StatusMessage(status));
synchronized (activePeers) {
if (activePeers.isEmpty()) {
return 0;
}
int numberOfPeersToSendStatusTo = getNumberOfPeersToSendStatusTo(activePeers.size());
List<Channel> shuffledPeers = new ArrayList<>(activePeers.values());
Collections.shuffle(shuffledPeers);
shuffledPeers.stream().limit(numberOfPeersToSendStatusTo).forEach(c -> c.sendMessage(message));
return numberOfPeersToSendStatusTo;
}
}
Aggregations