use of com.iota.iri.model.Hash in project iri by iotaledger.
the class Node method preProcessReceivedData.
public void preProcessReceivedData(byte[] receivedData, SocketAddress senderAddress, String uriScheme) {
TransactionViewModel receivedTransactionViewModel = null;
Hash receivedTransactionHash = null;
boolean addressMatch = false;
boolean cached = false;
for (final Neighbor neighbor : getNeighbors()) {
addressMatch = neighbor.matches(senderAddress);
if (addressMatch) {
// Validate transaction
neighbor.incAllTransactions();
if (rnd.nextDouble() < P_DROP_TRANSACTION) {
// log.info("Randomly dropping transaction. Stand by... ");
break;
}
try {
// Transaction bytes
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(receivedData, 0, TransactionViewModel.SIZE);
ByteBuffer byteHash = ByteBuffer.wrap(digest.digest());
// check if cached
synchronized (recentSeenBytes) {
cached = (receivedTransactionHash = recentSeenBytes.get(byteHash)) != null;
}
if (!cached) {
// if not, then validate
receivedTransactionViewModel = new TransactionViewModel(receivedData, Hash.calculate(receivedData, TransactionViewModel.TRINARY_SIZE, SpongeFactory.create(SpongeFactory.Mode.CURLP81)));
receivedTransactionHash = receivedTransactionViewModel.getHash();
TransactionValidator.runValidation(receivedTransactionViewModel, transactionValidator.getMinWeightMagnitude());
synchronized (recentSeenBytes) {
recentSeenBytes.put(byteHash, receivedTransactionHash);
}
// if valid - add to receive queue (receivedTransactionViewModel, neighbor)
addReceivedDataToReceiveQueue(receivedTransactionViewModel, neighbor);
}
} catch (NoSuchAlgorithmException e) {
log.error("MessageDigest: " + e);
} catch (final TransactionValidator.StaleTimestampException e) {
log.debug(e.getMessage());
try {
transactionRequester.clearTransactionRequest(receivedTransactionHash);
} catch (Exception e1) {
log.error(e1.getMessage());
}
neighbor.incInvalidTransactions();
} catch (final RuntimeException e) {
log.error(e.getMessage());
log.error("Received an Invalid TransactionViewModel. Dropping it...");
neighbor.incInvalidTransactions();
break;
}
// Request bytes
// add request to reply queue (requestedHash, neighbor)
Hash requestedHash = new Hash(receivedData, TransactionViewModel.SIZE, TransactionRequester.REQUEST_HASH_SIZE);
if (requestedHash.equals(receivedTransactionHash)) {
// requesting a random tip
requestedHash = Hash.NULL_HASH;
}
addReceivedDataToReplyQueue(requestedHash, neighbor);
if (debug) {
long hitCount, missCount;
if (cached) {
hitCount = recentSeenBytesHitCount.incrementAndGet();
missCount = recentSeenBytesMissCount.get();
} else {
hitCount = recentSeenBytesHitCount.get();
missCount = recentSeenBytesMissCount.incrementAndGet();
}
if (((hitCount + missCount) % 50000L == 0)) {
log.info("RecentSeenBytes cache hit/miss ratio: " + hitCount + "/" + missCount);
messageQ.publish("hmr %d/%d", hitCount, missCount);
recentSeenBytesMissCount.set(0L);
recentSeenBytesHitCount.set(0L);
}
}
break;
}
}
if (!addressMatch && configuration.booling(Configuration.DefaultConfSettings.TESTNET)) {
int maxPeersAllowed = configuration.integer(Configuration.DefaultConfSettings.MAX_PEERS);
String uriString = uriScheme + ":/" + senderAddress.toString();
if (Neighbor.getNumPeers() < maxPeersAllowed) {
log.info("Adding non-tethered neighbor: " + uriString);
messageQ.publish("antn %s", uriString);
try {
final URI uri = new URI(uriString);
// 3rd parameter false (not tcp), 4th parameter true (configured tethering)
final Neighbor newneighbor = newNeighbor(uri, false);
if (!getNeighbors().contains(newneighbor)) {
getNeighbors().add(newneighbor);
Neighbor.incNumPeers();
}
} catch (URISyntaxException e) {
log.error("Invalid URI string: " + uriString);
}
} else {
if (rejectedAddresses.size() > 20) {
// Avoid ever growing list in case of an attack.
rejectedAddresses.clear();
} else if (rejectedAddresses.add(uriString)) {
messageQ.publish("rntn %s %s", uriString, String.valueOf(maxPeersAllowed));
log.info("Refused non-tethered neighbor: " + uriString + " (max-peers = " + String.valueOf(maxPeersAllowed) + ")");
}
}
}
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class Node method sendPacket.
public void sendPacket(DatagramPacket sendingPacket, TransactionViewModel transactionViewModel, Neighbor neighbor) throws Exception {
// limit amount of sends per second
long now = System.currentTimeMillis();
if ((now - sendPacketsTimer.get()) > 1000L) {
// reset counter every second
sendPacketsCounter.set(0);
sendPacketsTimer.set(now);
}
if (sendLimit >= 0 && sendPacketsCounter.get() > sendLimit) {
// log.info("exceeded limit - don't send - {}",sendPacketsCounter.get());
return;
}
synchronized (sendingPacket) {
System.arraycopy(transactionViewModel.getBytes(), 0, sendingPacket.getData(), 0, TransactionViewModel.SIZE);
Hash hash = transactionRequester.transactionToRequest(rnd.nextDouble() < P_SELECT_MILESTONE);
System.arraycopy(hash != null ? hash.bytes() : transactionViewModel.getHash().bytes(), 0, sendingPacket.getData(), TransactionViewModel.SIZE, REQUEST_HASH_SIZE);
neighbor.send(sendingPacket);
}
sendPacketsCounter.getAndIncrement();
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class TransactionValidator method checkSolidity.
public boolean checkSolidity(Hash hash, boolean milestone) throws Exception {
if (TransactionViewModel.fromHash(tangle, hash).isSolid()) {
return true;
}
Set<Hash> analyzedHashes = new HashSet<>(Collections.singleton(Hash.NULL_HASH));
boolean solid = true;
final Queue<Hash> nonAnalyzedTransactions = new LinkedList<>(Collections.singleton(hash));
Hash hashPointer;
while ((hashPointer = nonAnalyzedTransactions.poll()) != null) {
if (analyzedHashes.add(hashPointer)) {
final TransactionViewModel transaction = TransactionViewModel.fromHash(tangle, hashPointer);
if (!transaction.isSolid()) {
if (transaction.getType() == TransactionViewModel.PREFILLED_SLOT && !hashPointer.equals(Hash.NULL_HASH)) {
transactionRequester.requestTransaction(hashPointer, milestone);
solid = false;
break;
} else {
if (solid) {
nonAnalyzedTransactions.offer(transaction.getTrunkTransactionHash());
nonAnalyzedTransactions.offer(transaction.getBranchTransactionHash());
}
}
}
}
}
if (solid) {
TransactionViewModel.updateSolidTransactions(tangle, analyzedHashes);
}
analyzedHashes.clear();
return solid;
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class TipsViewModel method getRandomNonSolidTipHash.
public Hash getRandomNonSolidTipHash() {
synchronized (sync) {
int size = tips.size();
if (size == 0) {
return null;
}
int index = seed.nextInt(size);
Iterator<Hash> hashIterator;
hashIterator = tips.iterator();
Hash hash = null;
while (index-- >= 0 && hashIterator.hasNext()) {
hash = hashIterator.next();
}
return hash;
// return tips.size() != 0 ? tips.get(seed.nextInt(tips.size())) : null;
}
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class TipsManager method serialUpdateRatings.
void serialUpdateRatings(final Set<Hash> visitedHashes, final Hash txHash, final Map<Hash, Long> ratings, final Set<Hash> analyzedTips, final Hash extraTip) throws Exception {
Stack<Hash> hashesToRate = new Stack<>();
hashesToRate.push(txHash);
Hash currentHash;
boolean addedBack;
while (!hashesToRate.empty()) {
currentHash = hashesToRate.pop();
TransactionViewModel transactionViewModel = TransactionViewModel.fromHash(tangle, currentHash);
addedBack = false;
Set<Hash> approvers = transactionViewModel.getApprovers(tangle).getHashes();
for (Hash approver : approvers) {
if (ratings.get(approver) == null && !approver.equals(currentHash)) {
if (!addedBack) {
addedBack = true;
hashesToRate.push(currentHash);
}
hashesToRate.push(approver);
}
}
if (!addedBack && analyzedTips.add(currentHash)) {
long rating = (extraTip != null && visitedHashes.contains(currentHash) ? 0 : 1) + approvers.stream().map(ratings::get).filter(Objects::nonNull).reduce((a, b) -> capSum(a, b, Long.MAX_VALUE / 2)).orElse(0L);
ratings.put(currentHash, rating);
}
}
}
Aggregations