elements) {
30 | GetTrytesResponse res = new GetTrytesResponse();
31 | res.trytes = elements.toArray(new String[] {});
32 | return res;
33 | }
34 |
35 | /**
36 | *
37 | * @return {@link #trytes}
38 | */
39 | public String [] getTrytes() {
40 | return trytes;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/dto/IXIResponse.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.dto;
2 |
3 | import com.iota.iri.IXI;
4 |
5 | /**
6 | *
7 | * When a command is not recognized by the default API, we try to process it as an IXI module.
8 | * IXI stands for Iota eXtension Interface. See {@link IXI} for more information.
9 | *
10 | *
11 | * The response will contain the reply that the IXI module gave.
12 | * This could be empty, depending on the module.
13 | *
14 | *
15 | * An example module can be found here: Snapshot.ixi
16 | *
17 | */
18 | public class IXIResponse extends AbstractResponse {
19 | private Object ixi;
20 |
21 | public static IXIResponse create(Object myixi) {
22 | IXIResponse ixiResponse = new IXIResponse();
23 | ixiResponse.ixi = myixi;
24 | return ixiResponse;
25 | }
26 |
27 | public Object getResponse() {
28 | return ixi;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/dto/RemoveNeighborsResponse.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.dto;
2 |
3 | import com.iota.iri.service.API;
4 |
5 | /**
6 | *
7 | * Contains information about the result of a successful {@code removeNeighbors} API call.
8 | * See {@link API#removeNeighborsStatement} for how this response is created.
9 | *
10 | */
11 | public class RemoveNeighborsResponse extends AbstractResponse {
12 |
13 | /**
14 | * The amount of temporarily removed neighbors from this node.
15 | * Can be 0 or more.
16 | */
17 | private int removedNeighbors;
18 |
19 | /**
20 | * Creates a new {@link RemoveNeighborsResponse}
21 | *
22 | * @param numberOfRemovedNeighbors {@link #removedNeighbors}
23 | * @return an {@link RemoveNeighborsResponse} filled with the number of removed neighbors
24 | */
25 | public static AbstractResponse create(int numberOfRemovedNeighbors) {
26 | RemoveNeighborsResponse res = new RemoveNeighborsResponse();
27 | res.removedNeighbors = numberOfRemovedNeighbors;
28 | return res;
29 | }
30 |
31 | /**
32 | *
33 | * @return {@link #removedNeighbors}
34 | */
35 | public int getRemovedNeighbors() {
36 | return removedNeighbors;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/dto/WereAddressesSpentFrom.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.dto;
2 |
3 | import com.iota.iri.service.API;
4 |
5 | /**
6 | *
7 | * Contains information about the result of a successful {@code wereAddressesSpentFrom} API call.
8 | * See {@link API#wereAddressesSpentFromStatement} for how this response is created.
9 | *
10 | */
11 | public class WereAddressesSpentFrom extends AbstractResponse {
12 |
13 | /**
14 | * States of the specified addresses in Boolean
15 | * Order of booleans is equal to order of the supplied addresses.
16 | */
17 | private boolean[] states;
18 |
19 | /**
20 | * Creates a new {@link WereAddressesSpentFrom}
21 | *
22 | * @param inclusionStates {@link #states}
23 | * @return a {@link WereAddressesSpentFrom} filled with the address states
24 | */
25 | public static AbstractResponse create(boolean[] inclusionStates) {
26 | WereAddressesSpentFrom res = new WereAddressesSpentFrom();
27 | res.states = inclusionStates;
28 | return res;
29 | }
30 |
31 | /**
32 | *
33 | * @return {@link #states}
34 | */
35 | public boolean[] getStates() {
36 | return states;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/stats/LagCalculator.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.stats;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | import com.iota.iri.controllers.TransactionViewModel;
7 | import com.iota.iri.model.Hash;
8 | import com.iota.iri.storage.Tangle;
9 | import com.iota.iri.utils.dag.RecentTransactionsGetter;
10 |
11 | /**
12 | * Computes the node lag using various metrics
13 | */
14 | public class LagCalculator {
15 | private int transactionCount;
16 | private RecentTransactionsGetter recentTransactionsGetter;
17 | private Tangle tangle;
18 |
19 | public LagCalculator(int transactionCount, Tangle tangle, RecentTransactionsGetter recentTransactionsGetter) {
20 | this.transactionCount = transactionCount;
21 | this.tangle = tangle;
22 | this.recentTransactionsGetter = recentTransactionsGetter;
23 | }
24 |
25 | public long getMedianArrivalLag() throws Exception {
26 | Collection recentTransactions = recentTransactionsGetter.getRecentTransactions(transactionCount);
27 |
28 | if (recentTransactions.isEmpty()) {
29 | return -1;
30 | }
31 |
32 | Long[] lags = recentTransactions.stream()
33 | .map(this::fromHash)
34 | .map(tx -> new Long(Math.abs(tx.getAttachmentTimestamp() - tx.getArrivalTime())))
35 | .toArray(Long[]::new);
36 |
37 | Arrays.sort(lags);
38 |
39 | int middle = lags.length / 2;
40 | long median = lags.length % 2 == 1 ?
41 | lags[middle] :
42 | (lags[middle-1] + lags[middle]) / 2;
43 |
44 | return median;
45 | }
46 |
47 | private TransactionViewModel fromHash(Hash hash) {
48 | try {
49 | return TransactionViewModel.fromHash(tangle, hash);
50 | } catch (Exception e) {
51 | throw new RuntimeException("failed to load transaction");
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/EntryPointSelector.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 |
5 | /**
6 | * Selects an entryPoint for tip selection.
7 | *
8 | * this point is used as the starting point where
9 | * the particle starts the random walk.
10 | *
11 | */
12 |
13 | public interface EntryPointSelector {
14 |
15 | /**
16 | *get an entryPoint for tip selection
17 | *
18 | *Uses depth to determine the entry point for
19 | *the random walk.
20 | *
21 | * @param depth Depth, in milestones. a notion of how deep to search for a good starting point.
22 | * @return Entry point for walk method
23 | * @throws Exception If DB fails to retrieve transactions
24 | */
25 | Hash getEntryPoint(int depth) throws Exception;
26 |
27 | /**
28 | *get an entryPoint for tip selection
29 | *
30 | *Uses depth to determine the entry point for
31 | *the random walk.
32 | *
33 | * @return Entry point for walk method
34 | * @throws Exception If DB fails to retrieve transactions
35 | */
36 | Hash getEntryPoint() throws Exception;
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/RatingCalculator.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 | import com.iota.iri.model.HashId;
5 | import com.iota.iri.utils.collections.interfaces.UnIterableMap;
6 |
7 | /**
8 | * Calculates the rating for a sub graph
9 | */
10 | public interface RatingCalculator {
11 |
12 | /**
13 | * Rating calculator
14 | *
15 | * Calculates the rating of all the transactions that reference
16 | * a given entry point.
17 | *
18 | *
19 | * @param entryPoint Transaction hash of a selected entry point.
20 | * @return Map
21 | * @throws Exception If DB fails to retrieve transactions
22 | */
23 |
24 | UnIterableMap calculate(Hash entryPoint) throws Exception;
25 |
26 | /**
27 | * Calculates rating for a single transactions
28 | *
29 | * @param transaction Transaction hash of transaction in question
30 | * @return Map
31 | * @throws Exception If DB fails to retrieve transaction
32 | */
33 | int calculateSingle(Hash transaction) throws Exception;
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/ReferenceChecker.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 |
5 | /**
6 | * Checks if a given transaction references another
7 | */
8 | public interface ReferenceChecker {
9 | boolean doesReference(Hash referencer, Hash target) throws Exception;
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/StartingTipSelector.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 |
5 | /**
6 | * Functional interface for selecting a tip to start backtracking from,
7 | * used in EntryPointSelectorCumulativeWeightThreshold.
8 | */
9 |
10 | public interface StartingTipSelector {
11 | Hash getTip() throws Exception;
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/TailFinder.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import java.util.Optional;
4 |
5 | import com.iota.iri.model.Hash;
6 |
7 | /**
8 | * Finds the tail of a bundle
9 | */
10 |
11 | @FunctionalInterface
12 | public interface TailFinder {
13 | /**
14 | *Method for finding tails of bundles
15 | *
16 | *
17 | * This method is used to find a tail (current_index=0) of a bundle,
18 | * given any transaction hash in the bundle.
19 | *
20 | *
21 | * @param hash The transaction hash of any transaction in the bundle.
22 | * @return Hash of the tail transaction.
23 | * @throws Exception If DB fails to retrieve transactions
24 | */
25 | Optional findTail(Hash hash) throws Exception;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/TipSelector.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import java.util.List;
4 | import java.util.Optional;
5 |
6 | import com.iota.iri.model.Hash;
7 |
8 | /**
9 | * Selects tips to be approved
10 | */
11 |
12 |
13 | public interface TipSelector {
14 |
15 | /**
16 | * Method for finding tips
17 | *
18 | *
19 | * This method is used to find tips for approval,
20 | * if reference is present then tips will also reference this transaction.
21 | *
22 | *
23 | * @param reference An optional transaction hash to be referenced by tips.
24 | * @return Transactions to approve
25 | * @throws Exception If DB fails to retrieve transactions
26 | */
27 | List getTransactionsToApprove(Optional reference) throws Exception;
28 |
29 | List getConfidences(List transactions) throws Exception;
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/WalkValidator.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 |
5 | /**
6 | * Validates consistency of tails.
7 | */
8 | @FunctionalInterface
9 | public interface WalkValidator {
10 |
11 | /**
12 | * Validation
13 | *
14 | * Checks if a given transaction is a valid tail.
15 | *
16 | *
17 | * @param transactionHash Transaction hash to validate consistency of.
18 | * @return True iff tail is valid.
19 | * @throws Exception If Validation fails to execute
20 | */
21 | boolean isValid(Hash transactionHash) throws Exception;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/Walker.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection;
2 |
3 | import com.iota.iri.model.Hash;
4 | import com.iota.iri.model.HashId;
5 | import com.iota.iri.utils.collections.interfaces.UnIterableMap;
6 |
7 | /**
8 | * Walks the tangle from an entry point towards tips
9 | *
10 | */
11 |
12 | public interface Walker {
13 |
14 | /**
15 | * Walk algorithm
16 | *
17 | * Starts from given entry point to select valid transactions to be used
18 | * as tips. It will output a valid transaction as a tip.
19 | *
20 | *
21 | * @param entryPoint Transaction hash to start walk from.
22 | * @param ratings Map of ratings for each transaction that references entryPoint.
23 | * @param walkValidator Used to validate consistency of tails.
24 | * @return Transaction hash of tip.
25 | * @throws Exception If DB fails to retrieve transactions
26 | */
27 | Hash walk(Hash entryPoint, UnIterableMap ratings, WalkValidator walkValidator) throws Exception;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/impl/EntryPointSelectorGenesisImpl.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import com.iota.iri.model.Hash;
4 | import com.iota.iri.service.tipselection.EntryPointSelector;
5 |
6 | import org.apache.commons.lang3.NotImplementedException;
7 |
8 | /**
9 | * Implementation of EntryPointSelector that always returns the Genesis transaction:
10 | * {@link Hash#NULL_HASH}
11 | * Used to as a starting point for the random walk.
12 | */
13 | public class EntryPointSelectorGenesisImpl implements EntryPointSelector {
14 |
15 | public EntryPointSelectorGenesisImpl() {
16 | }
17 |
18 | @Override
19 | public Hash getEntryPoint(int depth) {
20 | throw new NotImplementedException("Not supported");
21 | }
22 |
23 | @Override
24 | public Hash getEntryPoint() {
25 | return Hash.NULL_HASH;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/impl/RatingOne.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import com.iota.iri.controllers.ApproveeViewModel;
4 | import com.iota.iri.model.Hash;
5 | import com.iota.iri.model.HashId;
6 | import com.iota.iri.service.tipselection.RatingCalculator;
7 | import com.iota.iri.storage.Tangle;
8 | import com.iota.iri.utils.collections.impl.TransformingMap;
9 | import com.iota.iri.utils.collections.interfaces.UnIterableMap;
10 |
11 | import java.util.*;
12 |
13 | /**
14 | * Implementation of RatingCalculator that gives a uniform rating of 1 to each transaction.
15 | * Used to create uniform random walks.
16 | */
17 | public class RatingOne implements RatingCalculator {
18 |
19 | private final Tangle tangle;
20 |
21 | public RatingOne(Tangle tangle) {
22 | this.tangle = tangle;
23 | }
24 |
25 | public UnIterableMap calculate(Hash entryPoint) throws Exception {
26 | UnIterableMap rating = new TransformingMap<>(null, null);
27 |
28 | Queue queue = new LinkedList<>();
29 | queue.add(entryPoint);
30 | rating.put(entryPoint, 1);
31 |
32 | Hash hash;
33 |
34 | //traverse all transactions that reference entryPoint
35 | while ((hash = queue.poll()) != null) {
36 | Set approvers = ApproveeViewModel.load(tangle, hash).getHashes();
37 | for (Hash tx : approvers) {
38 | if (!rating.containsKey(tx)) {
39 | //add to rating w/ value "1"
40 | rating.put(tx, 1);
41 | queue.add(tx);
42 | }
43 | }
44 | }
45 | return rating;
46 | }
47 |
48 | @Override
49 | public int calculateSingle(Hash transaction) throws Exception {
50 | return 1;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/impl/ReferenceCheckerImpl.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import java.util.Arrays;
4 | import java.util.HashSet;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 | import java.util.Objects;
8 | import java.util.Queue;
9 |
10 | import com.iota.iri.controllers.TransactionViewModel;
11 | import com.iota.iri.model.Hash;
12 | import com.iota.iri.service.tipselection.ReferenceChecker;
13 | import com.iota.iri.storage.Tangle;
14 |
15 | import org.apache.commons.collections4.CollectionUtils;
16 |
17 | public class ReferenceCheckerImpl implements ReferenceChecker {
18 | private Tangle tangle;
19 |
20 | public ReferenceCheckerImpl(Tangle tangle) {
21 | this.tangle = tangle;
22 | }
23 |
24 | @Override
25 | public boolean doesReference(Hash referencer, Hash target) throws Exception {
26 | if (!TransactionViewModel.exists(tangle, referencer) ||
27 | !TransactionViewModel.exists(tangle, target)) {
28 | throw new IllegalStateException("Transactions not found");
29 | }
30 |
31 | HashSet visitedHashes = new HashSet<>();
32 | Queue queue = new LinkedList<>();
33 |
34 | // Run BFS scan to look for approvee
35 | queue.add(referencer);
36 | visitedHashes.add(referencer);
37 |
38 | while (CollectionUtils.isNotEmpty(queue)) {
39 | Hash currentHash = queue.remove();
40 |
41 | if (Objects.equals(currentHash, target)) {
42 | return true;
43 | }
44 |
45 | TransactionViewModel current = TransactionViewModel.fromHash(tangle, currentHash);
46 | List approveeHashes = Arrays.asList(
47 | current.getTrunkTransactionHash(),
48 | current.getBranchTransactionHash());
49 |
50 | for (Hash approveeHash : approveeHashes) {
51 | if(approveeHash != null && !visitedHashes.contains(approveeHash)) {
52 | queue.add(approveeHash);
53 | visitedHashes.add(approveeHash);
54 | }
55 | }
56 | }
57 |
58 | return false;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/impl/TailFinderImpl.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import com.iota.iri.controllers.TransactionViewModel;
4 | import com.iota.iri.model.Hash;
5 | import com.iota.iri.service.tipselection.TailFinder;
6 | import com.iota.iri.storage.Tangle;
7 |
8 | import java.util.Optional;
9 | import java.util.Set;
10 |
11 | /**
12 | * Implementation of TailFinder that given a transaction hash finds the tail of the associated bundle.
13 | *
14 | */
15 | public class TailFinderImpl implements TailFinder {
16 |
17 | private final Tangle tangle;
18 |
19 | public TailFinderImpl(Tangle tangle) {
20 | this.tangle = tangle;
21 | }
22 |
23 | @Override
24 | public Optional findTail(Hash hash) throws Exception {
25 | TransactionViewModel tx = TransactionViewModel.fromHash(tangle, hash);
26 | final Hash bundleHash = tx.getBundleHash();
27 | long index = tx.getCurrentIndex();
28 | while (index-- > 0 && bundleHash.equals(tx.getBundleHash())) {
29 | Set approvees = tx.getApprovers(tangle).getHashes();
30 | boolean foundApprovee = false;
31 | for (Hash approvee : approvees) {
32 | TransactionViewModel nextTx = TransactionViewModel.fromHash(tangle, approvee);
33 | if (nextTx.getCurrentIndex() == index && bundleHash.equals(nextTx.getBundleHash())) {
34 | tx = nextTx;
35 | foundApprovee = true;
36 | break;
37 | }
38 | }
39 | if (!foundApprovee) {
40 | break;
41 | }
42 | }
43 | if (tx.getCurrentIndex() == 0) {
44 | return Optional.of(tx.getHash());
45 | }
46 | return Optional.empty();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/service/tipselection/impl/WalkValidatorImpl.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import com.iota.iri.LedgerValidator;
4 | import com.iota.iri.conf.TipSelConfig;
5 | import com.iota.iri.controllers.TransactionViewModel;
6 | import com.iota.iri.model.Hash;
7 | import com.iota.iri.service.tipselection.WalkValidator;
8 | import com.iota.iri.storage.Tangle;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.*;
13 |
14 | /**
15 | * Implementation of WalkValidator that checks consistency of the ledger as part of validity checks.
16 | *
17 | * A transaction is only valid if:
18 | *
19 | * - it is a tail
20 | *
- all the history of the transaction is present (is solid)
21 | *
- the ledger is still consistent if the transaction is added
22 | * (balances of all addresses are correct and all signatures are valid)
23 | *
24 | */
25 | public class WalkValidatorImpl implements WalkValidator {
26 |
27 | private final Tangle tangle;
28 | private final Logger log = LoggerFactory.getLogger(WalkValidator.class);
29 | private final LedgerValidator ledgerValidator;
30 |
31 | private Map myDiff;
32 | private Set myApprovedHashes;
33 |
34 | public WalkValidatorImpl(Tangle tangle, LedgerValidator ledgerValidator) {
35 | this.tangle = tangle;
36 | this.ledgerValidator = ledgerValidator;
37 |
38 | myDiff = new HashMap<>();
39 | myApprovedHashes = new HashSet<>();
40 | }
41 |
42 | @Override
43 | public boolean isValid(Hash transactionHash) throws Exception {
44 |
45 | if (Hash.NULL_HASH.equals(transactionHash)) {
46 | return true; //Genesis
47 | }
48 |
49 | TransactionViewModel transactionViewModel = TransactionViewModel.fromHash(tangle, transactionHash);
50 | if (transactionViewModel.getType() == TransactionViewModel.PREFILLED_SLOT) {
51 | log.debug("Validation failed: {} is missing in db", transactionHash);
52 | return false;
53 | } else if (transactionViewModel.getCurrentIndex() != 0) {
54 | log.debug("Validation failed: {} not a tail", transactionHash);
55 | return false;
56 | } else if (!transactionViewModel.isSolid()) {
57 | log.debug("Validation failed: {} is not solid", transactionHash);
58 | return false;
59 | } else if (!ledgerValidator.updateDiff(myApprovedHashes, myDiff, transactionViewModel.getHash())) {
60 | log.debug("Validation failed: {} is not consistent", transactionHash);
61 | return false;
62 | }
63 | return true;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/storage/Indexable.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.storage;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by paul on 5/6/17.
7 | */
8 | public interface Indexable extends Comparable, Serializable {
9 | byte[] bytes();
10 | void read(byte[] bytes);
11 | Indexable incremented();
12 | Indexable decremented();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/storage/Persistable.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.storage;
2 |
3 | import java.io.Serializable;
4 |
5 | public interface Persistable extends Serializable {
6 | byte[] bytes();
7 | void read(byte[] bytes);
8 | byte[] metadata();
9 | void readMetadata(byte[] bytes);
10 | boolean merge();
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/storage/PersistenceProvider.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.storage;
2 |
3 | import com.iota.iri.utils.Pair;
4 |
5 | import java.util.Collection;
6 | import java.util.List;
7 | import java.util.Set;
8 |
9 | /**
10 | * Created by paul on 3/2/17 for iri.
11 | */
12 | public interface PersistenceProvider {
13 |
14 | void init() throws Exception;
15 | boolean isAvailable();
16 | void shutdown();
17 | boolean save(Persistable model, Indexable index) throws Exception;
18 | void delete(Class> model, Indexable index) throws Exception;
19 |
20 | boolean update(Persistable model, Indexable index, String item) throws Exception;
21 |
22 | boolean exists(Class> model, Indexable key) throws Exception;
23 |
24 | Pair latest(Class> model, Class> indexModel) throws Exception;
25 |
26 | Set keysWithMissingReferences(Class> modelClass, Class> otherClass) throws Exception;
27 |
28 | Persistable get(Class> model, Indexable index) throws Exception;
29 |
30 | boolean mayExist(Class> model, Indexable index) throws Exception;
31 |
32 | long count(Class> model) throws Exception;
33 |
34 | Set keysStartingWith(Class> modelClass, byte[] value);
35 |
36 | Persistable seek(Class> model, byte[] key) throws Exception;
37 |
38 | Pair next(Class> model, Indexable index) throws Exception;
39 | Pair previous(Class> model, Indexable index) throws Exception;
40 |
41 | Pair first(Class> model, Class> indexModel) throws Exception;
42 |
43 | boolean saveBatch(List> models) throws Exception;
44 |
45 | /**
46 | * Atomically delete all {@code models}.
47 | * @param models key value pairs that to be expunged from the db
48 | * @throws Exception
49 | */
50 | void deleteBatch(Collection>> models) throws Exception;
51 |
52 | void clear(Class> column) throws Exception;
53 | void clearMetadata(Class> column) throws Exception;
54 | void clearAll() throws Exception;
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/IotaIOUtils.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 |
4 | import org.apache.commons.io.IOUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | public class IotaIOUtils extends IOUtils {
9 |
10 | private static final Logger log = LoggerFactory.getLogger(IotaIOUtils.class);
11 |
12 | public static void closeQuietly(AutoCloseable... autoCloseables) {
13 | for (AutoCloseable it : autoCloseables) {
14 | try {
15 | if (it != null) {
16 | it.close();
17 | }
18 | } catch (Exception ignored) {
19 | log.debug("Silent exception occured", ignored);
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/IotaUtils.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 |
5 | import com.iota.iri.model.Hash;
6 |
7 | import java.lang.reflect.Method;
8 | import java.nio.ByteBuffer;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 | import java.util.stream.Stream;
15 |
16 | public class IotaUtils {
17 |
18 | public static List splitStringToImmutableList(String string, String regexSplit) {
19 | return Arrays.stream(string.split(regexSplit))
20 | .filter(StringUtils::isNoneBlank)
21 | .collect(Collectors
22 | .collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
23 | }
24 |
25 | /**
26 | * Used to create low-memory index keys.
27 | *
28 | * @param hash the hash we create the key from
29 | * @param length the length of the desired subhash
30 | * @return a {@link ByteBuffer} that holds a subarray of {@link Hash#bytes()}
31 | * that has the specified {@code length}
32 | */
33 | public static ByteBuffer getSubHash(Hash hash, int length) {
34 | if (hash == null) {
35 | return null;
36 | }
37 |
38 | return ByteBuffer.wrap(Arrays.copyOf(hash.bytes(), length));
39 | }
40 |
41 | /**
42 | * @param clazz Class to inspect
43 | * @return All the declared and inherited setter method of {@code clazz}
44 | */
45 | public static List getAllSetters(Class> clazz) {
46 | List setters = new ArrayList<>();
47 | while (clazz != Object.class) {
48 | setters.addAll(Stream.of(clazz.getDeclaredMethods())
49 | .filter(method -> method.getName().startsWith("set"))
50 | .collect(Collectors.toList()));
51 | clazz = clazz.getSuperclass();
52 | }
53 | return Collections.unmodifiableList(setters);
54 | }
55 |
56 | public static List createImmutableList(T... values) {
57 | return Collections.unmodifiableList(Arrays.asList(values));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/Pair.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | public class Pair {
4 | public final S low;
5 | public final T hi;
6 |
7 | public Pair(S k, T v) {
8 | low = k;
9 | hi = v;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/SafeUtils.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | import java.util.Collection;
4 |
5 |
6 | /**
7 | * Null safe utils
8 | */
9 | public class SafeUtils {
10 |
11 | public static boolean isContaining(Collection collection, T element) {
12 | return collection != null && element != null && collection.contains(element);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/Serializer.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | /**
4 | * Created by paul on 3/13/17 for iri-testnet.
5 | */
6 | public class Serializer {
7 | public static byte[] serialize(long value) {
8 | byte[] result = new byte[Long.BYTES];
9 | for (int i = Long.BYTES - 1; i >= 0; i--) {
10 | result[i] = (byte)(value & 0xFF);
11 | value >>= 8;
12 | }
13 | return result;
14 | }
15 |
16 | public static byte[] serialize(int integer) {
17 | byte[] result = new byte[Integer.BYTES];
18 | for (int i = Integer.BYTES - 1; i >= 0; i--) {
19 | result[i] = (byte)(integer & 0xFF);
20 | integer >>= 8;
21 | }
22 | return result;
23 | }
24 |
25 | public static long getLong(byte[] bytes) {
26 | return getLong(bytes, 0);
27 | }
28 | public static long getLong(byte[] bytes, int start) {
29 | if(bytes == null) {
30 | return 0;
31 | }
32 | int length = Long.BYTES;
33 | long res = 0;
34 | for (int i=0; i< length;i++) {
35 | res |= (bytes[start + i] & 0xFFL) << ((length-i-1) * 8);
36 | }
37 | return res;
38 | }
39 |
40 | public static int getInteger(byte[] bytes) {
41 | return getInteger(bytes, 0);
42 | }
43 | public static int getInteger(byte[] bytes, int start) {
44 | if(bytes == null) {
45 | return 0;
46 | }
47 | int length = Integer.BYTES;
48 | int res = 0;
49 | for (int i=0; i< length;i++) {
50 | res |= (bytes[start + i] & 0xFFL) << ((length-i-1) * 8);
51 | }
52 | return res;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/SlackBotFeed.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 | import java.net.URLEncoder;
9 |
10 | import javax.net.ssl.HttpsURLConnection;
11 |
12 | public class SlackBotFeed {
13 |
14 | public static void reportToSlack(final String message) {
15 |
16 | try {
17 |
18 | final String request = "token="
19 | + URLEncoder.encode("", "UTF-8") + "&channel="
20 | + URLEncoder.encode("#botbox", "UTF-8") + "&text=" + URLEncoder.encode(message, "UTF-8") + "&as_user=true";
21 |
22 | final HttpURLConnection connection = (HttpsURLConnection) (new URL("https://slack.com/api/chat.postMessage")).openConnection();
23 | ((HttpsURLConnection)connection).setHostnameVerifier((hostname, session) -> true);
24 | connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
25 | connection.setRequestMethod("POST");
26 | connection.setDoOutput(true);
27 | OutputStream out = connection.getOutputStream();
28 | out.write(request.getBytes("UTF-8"));
29 | out.close();
30 | ByteArrayOutputStream result = new ByteArrayOutputStream();
31 | InputStream inputStream = connection.getInputStream();
32 | byte[] buffer = new byte[1024];
33 | int length;
34 | while ((length = inputStream.read(buffer)) != -1) {
35 | result.write(buffer, 0, length);
36 | }
37 |
38 | } catch (final Exception e) {
39 |
40 | e.printStackTrace();
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/impl/BoundedHashSet.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.impl;
2 |
3 | import com.iota.iri.utils.collections.interfaces.BoundedSet;
4 |
5 | import java.util.Collection;
6 | import java.util.HashSet;
7 | import java.util.stream.Collectors;
8 |
9 |
10 | /**
11 | * A set that doesn't allow to add elements to it once it is full
12 | *
13 | * @param the type parameter
14 | */
15 | public class BoundedHashSet extends HashSet implements BoundedSet{
16 | final private int maxSize;
17 |
18 | /**
19 | * Instantiates a new Bounded hash set.
20 | *
21 | * @param initialCapacity the initial capacity
22 | * @param loadFactor the load factor of the hashmap
23 | * @param maxSize the max size
24 | */
25 | public BoundedHashSet(int initialCapacity, float loadFactor, int maxSize) {
26 | super(initialCapacity, loadFactor);
27 | this.maxSize = maxSize;
28 | }
29 |
30 | /**
31 | * Instantiates a new Bounded hash set.
32 | *
33 | * @param initialCapacity the initial capacity
34 | * @param maxSize the max size
35 | */
36 | public BoundedHashSet(int initialCapacity, int maxSize) {
37 | super(initialCapacity);
38 | this.maxSize = maxSize;
39 | }
40 |
41 | /**
42 | * Instantiates a new Bounded hash set.
43 | *
44 | * @param maxSize the max size
45 | */
46 | public BoundedHashSet(int maxSize) {
47 | super();
48 | this.maxSize = maxSize;
49 | }
50 |
51 | /**
52 | * Instantiates a new Bounded hash set.
53 | *
54 | * @param c the collection from which you create the set from
55 | * @param maxSize the max size
56 | * @throws NullPointerException if the specified collection is null
57 | */
58 | public BoundedHashSet(Collection extends E> c, int maxSize) {
59 | this(maxSize);
60 | c = c.stream()
61 | .limit(maxSize)
62 | .collect(Collectors.toSet());
63 | this.addAll(c);
64 | }
65 |
66 | @Override
67 | public int getMaxSize() {
68 | return maxSize;
69 | }
70 |
71 | @Override
72 | public boolean add(E e) {
73 | if (isFull()) {
74 | return false;
75 | }
76 |
77 | return super.add(e);
78 | }
79 |
80 | @Override
81 | public boolean addAll(Collection extends E> c) {
82 | if (isFull()) {
83 | return false;
84 | }
85 |
86 | if (!canCollectionBeFullyAdded(c)) {
87 | int remainingSize = getMaxSize() - this.size();
88 | c = c.stream()
89 | .limit(remainingSize)
90 | .collect(Collectors.toSet());
91 | }
92 | return super.addAll(c);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/impl/TransformingBoundedHashSet.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.impl;
2 |
3 | import java.util.Collection;
4 | import java.util.function.UnaryOperator;
5 | import java.util.stream.Collectors;
6 |
7 |
8 | public class TransformingBoundedHashSet extends BoundedHashSet{
9 |
10 | private final UnaryOperator transformer;
11 |
12 | public TransformingBoundedHashSet(int maxSize, UnaryOperator transformer) {
13 | super(maxSize);
14 | this.transformer = transformer;
15 | }
16 |
17 | public TransformingBoundedHashSet(Collection c, int maxSize, UnaryOperator transformer) {
18 | super(maxSize);
19 | this.transformer = transformer;
20 | this.addAll(c);
21 | }
22 |
23 | @Override
24 | public boolean add(E e) {
25 | if (isFull()) {
26 | return false;
27 | }
28 |
29 | E el = transformer.apply(e);
30 | return super.add(el);
31 | }
32 |
33 | @Override
34 | public boolean addAll(Collection extends E> c) {
35 | Collection extends E> col = c;
36 | if (!isFull()) {
37 | col = c.stream()
38 | .map(el -> transformer.apply(el))
39 | .collect(Collectors.toSet());
40 | }
41 | return super.addAll(col);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/impl/TransformingMap.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.impl;
2 |
3 | import com.iota.iri.utils.collections.interfaces.UnIterableMap;
4 |
5 | import java.util.Collection;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.function.UnaryOperator;
9 |
10 | /**
11 | * A map that performs unary operations on key-value pairs that are inserted into it.
12 | *
13 | * @param key type
14 | * @param value type
15 | */
16 | public class TransformingMap implements UnIterableMap {
17 | private Map delegateMap;
18 | private UnaryOperator keyOptimizer;
19 | private UnaryOperator valueTransformer;
20 |
21 | public TransformingMap(UnaryOperator keyOptimizer, UnaryOperator valueTransformer) {
22 | this(16, keyOptimizer, valueTransformer);
23 | }
24 |
25 | public TransformingMap(int initialCapacity, UnaryOperator keyOptimizer, UnaryOperator valueTransformer) {
26 | this.keyOptimizer = keyOptimizer == null ? UnaryOperator.identity() : keyOptimizer;
27 | this.valueTransformer = valueTransformer == null ? UnaryOperator.identity() : valueTransformer;
28 |
29 | this.delegateMap = new HashMap<>(initialCapacity);
30 | }
31 |
32 | @Override
33 | public int size() {
34 | return delegateMap.size();
35 | }
36 |
37 | @Override
38 | public boolean isEmpty() {
39 | return delegateMap.isEmpty();
40 | }
41 |
42 | @Override
43 | public boolean containsKey(K key) {
44 | K newKey = keyOptimizer.apply(key);
45 | return delegateMap.containsKey(newKey);
46 | }
47 |
48 | @Override
49 | public boolean containsValue(V value) {
50 | return delegateMap.containsValue(value);
51 | }
52 |
53 | @Override
54 | public V get(K key) {
55 | K newKey = keyOptimizer.apply(key);
56 | return delegateMap.get(newKey);
57 | }
58 |
59 | @Override
60 | public V put(K key, V value) {
61 | key = keyOptimizer.apply(key);
62 | value = valueTransformer.apply(value);
63 | return delegateMap.put(key, value);
64 | }
65 |
66 | @Override
67 | public V remove(K key) {
68 | return delegateMap.remove(key);
69 | }
70 |
71 | @Override
72 | public void clear() {
73 | delegateMap.clear();
74 | }
75 |
76 | @Override
77 | public Collection values() {
78 | return delegateMap.values();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/interfaces/BoundedCollection.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.interfaces;
2 |
3 | import java.util.Collection;
4 |
5 | /**
6 | * A collection that can't hold more than {@link #getMaxSize()} elements
7 | *
8 | * @author galrogo on 08/02/18
9 | **/
10 | public interface BoundedCollection extends Collection {
11 |
12 | /**
13 | *
14 | * @return the maximal number of elements that the collection cha hold
15 | */
16 | int getMaxSize();
17 |
18 | /**
19 | * @return true if no more elements can be added
20 | */
21 | default boolean isFull() {
22 | return getMaxSize() <= this.size();
23 | }
24 |
25 | /**
26 | *
27 | * @param c collection to be added
28 | * @return true only if all the elements in {@code c} can be added to this collection
29 | * else return false
30 | */
31 | default boolean canCollectionBeFullyAdded(Collection extends E> c) {
32 | if (isFull()) {
33 | return false;
34 | }
35 |
36 | int remainingSize = getMaxSize() - this.size();
37 | return (c.size() <= remainingSize);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/interfaces/BoundedSet.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.interfaces;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | * A set that can't hold more than {@link #getMaxSize()} elements
7 | *
8 | * @author galrogo on 08/02/18
9 | **/
10 | public interface BoundedSet extends BoundedCollection, Set{
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/collections/interfaces/UnIterableMap.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.interfaces;
2 |
3 | import java.util.Collection;
4 | import java.util.Map;
5 |
6 |
7 | /**
8 | * Similar to {@link Map} but hides key retrieval functionality.
9 | * Thus one can't iterate over key or entries.
10 | * Implementing class may transform keys to perform memory operations
11 | *
12 | * @param The key type
13 | * @param The value type
14 | */
15 | public interface UnIterableMap {
16 |
17 |
18 | /**
19 | * {See {@link Map#size()}}
20 | */
21 | int size();
22 |
23 | /**
24 | * {See {@link Map#isEmpty()}}
25 | */
26 | boolean isEmpty();
27 |
28 | /**
29 | * {See {@link Map#containsKey(Object)}}
30 | */
31 | boolean containsKey(K key);
32 |
33 | /**
34 | * {See {@link Map#containsValue(Object)}}
35 | */
36 | boolean containsValue(V value);
37 |
38 | /**
39 | *
40 | * {See {@link Map#get}}
41 | */
42 | V get(K key);
43 |
44 | /**
45 | * {See {@link Map#put}
46 | */
47 | V put(K key, V value);
48 |
49 | /**
50 | * {See {@link Map#keySet()}}
51 | */
52 | V remove(K key);
53 |
54 | /**
55 | * {See {@link Map#clear()}}
56 | */
57 | void clear();
58 |
59 | /**
60 | * {See {@link Map#values}
61 | */
62 | Collection values();
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/dag/RecentTransactionsGetter.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.dag;
2 |
3 | import java.util.Collection;
4 |
5 | import com.iota.iri.model.Hash;
6 |
7 | /**
8 | * Get N most recent transactions
9 | */
10 | public interface RecentTransactionsGetter {
11 | Collection getRecentTransactions(int count) throws Exception;
12 | }
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/dag/TraversalException.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.dag;
2 |
3 | /**
4 | * This class is used to wrap exceptions that are specific to traversing the graph.
5 | *
6 | * It allows us to distinct between the different kinds of errors that can happen during the execution of the code.
7 | */
8 | public class TraversalException extends Exception {
9 | /**
10 | * Constructor of the exception which allows us to provide a specific error message and the cause of the error.
11 | *
12 | * @param message reason why this error occured
13 | * @param cause wrapped exception that caused this error
14 | */
15 | public TraversalException(String message, Throwable cause) {
16 | super(message, cause);
17 | }
18 |
19 | /**
20 | * Constructor of the exception which allows us to provide a specific error message without having an underlying
21 | * cause.
22 | *
23 | * @param message reason why this error occured
24 | */
25 | public TraversalException(String message) {
26 | super(message);
27 | }
28 |
29 | /**
30 | * Constructor of the exception which allows us to wrap the underlying cause of the error without providing a
31 | * specific reason.
32 | *
33 | * @param cause wrapped exception that caused this error
34 | */
35 | public TraversalException(Throwable cause) {
36 | super(cause);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/log/Logger.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.log;
2 |
3 | /**
4 | * Represents a wrapper for the logback Logger, which allows us to add aditional features to the logging capabilities of
5 | * IRI.
6 | */
7 | public interface Logger {
8 | /**
9 | * This method allows us to set a new info message that shall get printed to the screen.
10 | *
11 | * @param message info message that shall get printed
12 | * @return the logger itself to allow the chaining of calls
13 | */
14 | Logger info(String message);
15 |
16 | /**
17 | * This method allows us to set a new debug message that shall get printed to the screen.
18 | *
19 | * @param message debug message that shall get printed
20 | * @return the logger itself to allow the chaining of calls
21 | */
22 | Logger debug(String message);
23 |
24 | /**
25 | * This method allows us to set a new error message that shall get printed to the screen.
26 | *
27 | * @param message debug message that shall get printed
28 | * @return the logger itself to allow the chaining of calls
29 | */
30 | Logger error(String message);
31 |
32 | /**
33 | * This method allows us to set a new error message that shall get printed to the screen.
34 | *
35 | * @param message debug message that shall get printed
36 | * @param cause exception object that caused the error to happen (will be printed with the complete stacktrace)
37 | */
38 | Logger error(String message, Throwable cause);
39 |
40 | /**
41 | * This method is the getter for the enabled flag of the logger.
42 | *
43 | * If the logger is disabled it will simply omit showing log messages.
44 | *
45 | * @return true if the logger shall output messages and false otherwise (the logger is enabled by default)
46 | */
47 | boolean getEnabled();
48 |
49 | /**
50 | * This method is the setter for the enabled flag of the logger.
51 | *
52 | * If the logger is disabled it will simply omit showing log messages.
53 | *
54 | * @param enabled true if the logger shall output messages and false otherwise (the logger is enabled by default)
55 | * @return the logger itself to allow the chaining of calls
56 | */
57 | Logger setEnabled(boolean enabled);
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/thread/ReportingExecutorService.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.thread;
2 |
3 | /**
4 | * This interface defines a contract for {@link java.util.concurrent.ExecutorService}s that makes them call a
5 | * "reporting" method whenever an important event occurs.
6 | *
7 | * This way a child class extending these kind of {@link java.util.concurrent.ExecutorService}s can "hook" into these
8 | * events by overriding the specific method and add additional logic like logging or debugging capabilities.
9 | */
10 | public interface ReportingExecutorService {
11 | /**
12 | * This method gets called whenever a new task is scheduled to run.
13 | *
14 | * In contrast to {@link #onStartTask(TaskDetails)} this method gets called only once for "recurring" tasks that are
15 | * scheduled to run in pre-defined intervals.
16 | *
17 | * @param taskDetails object containing details about this task
18 | */
19 | void onScheduleTask(TaskDetails taskDetails);
20 |
21 | /**
22 | * This method gets called whenever a task is started.
23 | *
24 | * For recurring tasks it is called multiple times.
25 | *
26 | * @param taskDetails object containing details about this task
27 | */
28 | void onStartTask(TaskDetails taskDetails);
29 |
30 | /**
31 | * This method gets called whenever a task is finished.
32 | *
33 | * For recurring tasks it is called multiple times.
34 | *
35 | * @param taskDetails object containing details about this task
36 | * @param error {@link Exception} that caused the task to complete
37 | */
38 | void onFinishTask(TaskDetails taskDetails, Throwable error);
39 |
40 | /**
41 | * This method gets called whenever a task is cancelled through its {@link java.util.concurrent.Future} or through
42 | * the shutdown methods of the {@link java.util.concurrent.ExecutorService}.
43 | *
44 | * It only gets called once for every task.
45 | *
46 | * @param taskDetails object containing details about this task
47 | */
48 | void onCancelTask(TaskDetails taskDetails);
49 |
50 | /**
51 | * This method gets called whenever a task completes.
52 | *
53 | * This can be through either raising an exception, cancelling from the outside or by simply terminating in a normal
54 | * manner. For recurring tasks this only gets called once.
55 | *
56 | * @param taskDetails object containing details about this task
57 | * @param error {@link Exception} that caused the task to complete
58 | */
59 | void onCompleteTask(TaskDetails taskDetails, Throwable error);
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/utils/thread/ThreadIdentifier.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.thread;
2 |
3 | /**
4 | * The instances of this class are used by the {@link ThreadUtils} to map the {@link Thread}s and make the corresponding
5 | * spawn and stop methods thread safe.
6 | */
7 | public class ThreadIdentifier {
8 | /**
9 | * Holds the name of the {@link Thread}.
10 | */
11 | private final String name;
12 |
13 | /**
14 | * The constructor simply stores the passed in name in the private property of this instance.
15 | *
16 | * While the name is not required to identify the {@link Thread}, we still require to give one to be able to create
17 | * meaningful log messages.
18 | *
19 | * @param name name of the {@link Thread} that get referenced by this identifier.
20 | */
21 | public ThreadIdentifier(String name) {
22 | this.name = name;
23 | }
24 |
25 | /**
26 | * Getter of the name that was used to create this identifier.
27 | *
28 | * It simply returns the internal property.
29 | *
30 | * @return name of the {@link Thread} that this identifier references
31 | */
32 | public String getName() {
33 | return name;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/iota/iri/zmq/README.md:
--------------------------------------------------------------------------------
1 | ## IRI MessageQ
2 |
3 | MessageQ is a small wrapper for ZeroMQ inside IRI to allow streaming
4 | of topics from within a running full node. The goal of this is to allow
5 | for targeted event streams from subscribing clients to the node process.
6 |
7 | A client may want to be notified of a change in status of a transaction,
8 | or may want to see incoming transactions, or any number of data points.
9 | These can be filtered by topic, and the aim is for machine-readability
10 | over human readability.
11 |
12 | For instance, a light wallet connected to a remote node may want to know
13 | when a transaction is confirmed. It would, perhaps, after querying the API,
14 | subscribe to a topic which publishes on the update of a state.
15 |
16 | #### Topics
17 |
18 | A client interested in tip selection metrics may subscribe to `mctn`, short for
19 | "monte carlo transaction number", a metric that indicates how many transactions
20 | were traversed in a random walk simulation. It may subscribe to `rts`, for
21 | "reason to stop", to see information about walk terminations.
22 |
23 | Topics currently found in the latest code are
24 | * `mctn` transactions traversed during random walk
25 | * `rts` information about walk terminations
26 | * `dnscv` neighbor DNS validations
27 | * `dnscc` neighbor DNS confirmations
28 | * `dnscu` neighbor DNS updates
29 | * `hmr` for the hit to miss ratio
30 | * `antn` for added non-tethered neighbors ( testnet only )
31 | * `rntn` for refused non-tethered neighbors
32 | * `rstat` for information about the tips requester
33 | * `rtl` for transactions randomly removed from the request list
34 | * `lmi` for the latest milestone index
35 | * `lmsi` for the latest solid milestone index
36 | * `lmhs` for the latest solid milestone hash
37 | * `sn` for newly confirmed transactions ( by solid milestone children measurement )
38 | * `tx` for newly seen transactions
39 | * `tx_trytes` trytes of newly seen transactions
40 | * `ct5m2h` confirmed transactions older than 5m and younger than 2h
41 | * `t5m2h` total transactions older than 5m and younger than 2h
42 | * `` to watch activity on an address
43 |
44 | All topic must be lowercase (to not clash with `` containing the topic title - like `TXCR9...` & `TX`)
45 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | System.out
6 |
7 | TRACE
8 | ACCEPT
9 | NEUTRAL
10 |
11 |
12 | DEBUG
13 | ACCEPT
14 | NEUTRAL
15 |
16 |
17 | INFO
18 | ACCEPT
19 | NEUTRAL
20 |
21 |
22 | WARN
23 | ACCEPT
24 | DENY
25 |
26 |
27 | %d{MM/dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
28 |
29 |
30 |
31 |
32 |
33 | System.err
34 |
35 | ERROR
36 | ACCEPT
37 | DENY
38 |
39 |
40 | %d{MM/dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/IXITest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri;
2 |
3 | import com.iota.iri.service.dto.AbstractResponse;
4 | import com.iota.iri.service.dto.IXIResponse;
5 | import org.junit.AfterClass;
6 | import org.junit.BeforeClass;
7 | import org.junit.Test;
8 | import org.junit.rules.TemporaryFolder;
9 |
10 | public class IXITest {
11 | static TemporaryFolder ixiDir = new TemporaryFolder();
12 | static IXI ixi;
13 |
14 | @BeforeClass
15 | public static void setUp() throws Exception {
16 | ixiDir.create();
17 | ixi = new IXI();
18 | ixi.init(ixiDir.getRoot().getAbsolutePath().toString());
19 | }
20 |
21 | @AfterClass
22 | public static void tearDown() throws Exception {
23 | ixi.shutdown();
24 | ixiDir.delete();
25 | }
26 |
27 | @Test
28 | public void init() throws Exception {
29 | AbstractResponse response;
30 | IXIResponse ixiResponse;
31 |
32 | /*
33 | final String testJs =
34 | "var Callable = Java.type(\"com.iota.iri.service.CallableRequest\");\n" +
35 | "print(\"hello world\");\n" +
36 | "var IXIResponse = Java.type(\"com.iota.iri.service.dto.IXIResponse\");\n" +
37 | "API.put(\"getParser\", new Callable({\n" +
38 | "call: function(req) {\n" +
39 | "var IntArray = Java.type(\"int[]\");\n" +
40 | "var out = new IntArray(Math.floor(Math.random()*9)+1);\n" +
41 | "out[0] = 2;\n" +
42 | "var r = IXIResponse.create({\n" +
43 | "myArray: out,\n" +
44 | "name: \"Foo\"\n" +
45 | "});\n" +
46 | "return r;\n" +
47 | "}\n" +
48 | "}));";
49 | final String testPackage = "{\"main\": \"index.js\"}";
50 |
51 |
52 | ixiDir.newFolder("test");
53 | try (OutputStream out = new BufferedOutputStream(
54 | Files.newOutputStream(Paths.get(ixiDir.getRoot().toString(),"test", "index.js"), CREATE))) {
55 | out.write(testJs.getBytes());
56 | }
57 | try (OutputStream out = new BufferedOutputStream(
58 | Files.newOutputStream(Paths.get(ixiDir.getRoot().toString(),"test", "package.json"), CREATE))) {
59 | out.write(testPackage.getBytes());
60 | }
61 | // Allow IXI to load the file
62 | Map request = new HashMap<>();
63 | Thread.sleep(1000);
64 | response = IXI.instance().processCommand("test.getParser", request);
65 |
66 | assertFalse(response instanceof ErrorResponse);
67 | assertTrue(response instanceof IXIResponse);
68 |
69 | ixiResponse = ((IXIResponse) response);
70 | assertNotNull(ixiResponse.getResponse());
71 | */
72 | }
73 |
74 | @Test
75 | public void processCommand() throws Exception {
76 |
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/benchmarks/BenchmarkRunner.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.benchmarks;
2 |
3 | import com.iota.iri.benchmarks.dbbenchmark.RocksDbBenchmark;
4 | import org.junit.Test;
5 | import org.openjdk.jmh.annotations.Mode;
6 | import org.openjdk.jmh.runner.Runner;
7 | import org.openjdk.jmh.runner.RunnerException;
8 | import org.openjdk.jmh.runner.options.Options;
9 | import org.openjdk.jmh.runner.options.OptionsBuilder;
10 |
11 | import java.util.concurrent.TimeUnit;
12 |
13 | public class BenchmarkRunner {
14 |
15 | @Test
16 | public void launchDbBenchmarks() throws RunnerException {
17 | Options opts = new OptionsBuilder()
18 | .include(RocksDbBenchmark.class.getName() + ".*")
19 | .mode(Mode.AverageTime)
20 | .timeUnit(TimeUnit.MILLISECONDS)
21 | .warmupIterations(5)
22 | .forks(1)
23 | .measurementIterations(10)
24 | .shouldFailOnError(true)
25 | .shouldDoGC(false)
26 | .build();
27 |
28 | //possible to do assertions over run results
29 | new Runner(opts).run();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/benchmarks/dbbenchmark/RocksDbBenchmark.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.benchmarks.dbbenchmark;
2 |
3 | import com.iota.iri.benchmarks.dbbenchmark.states.EmptyState;
4 | import com.iota.iri.benchmarks.dbbenchmark.states.FullState;
5 | import com.iota.iri.controllers.TransactionViewModel;
6 | import com.iota.iri.model.persistables.Transaction;
7 | import com.iota.iri.storage.Indexable;
8 | import com.iota.iri.storage.Persistable;
9 | import com.iota.iri.utils.Pair;
10 | import org.openjdk.jmh.annotations.Benchmark;
11 |
12 |
13 | public class RocksDbBenchmark {
14 |
15 | @Benchmark
16 | public void persistOneByOne(EmptyState state) throws Exception {
17 | for (TransactionViewModel tvm: state.getTransactions()) {
18 | tvm.store(state.getTangle());
19 | }
20 | }
21 |
22 | @Benchmark
23 | public void deleteOneByOne(FullState state) throws Exception {
24 | for (TransactionViewModel tvm : state.getTransactions()) {
25 | tvm.delete(state.getTangle());
26 | }
27 | }
28 |
29 | @Benchmark
30 | public void dropAll(FullState state) throws Exception {
31 | state.getTangle().clearColumn(Transaction.class);
32 | state.getTangle().clearMetadata(Transaction.class);
33 | }
34 |
35 | @Benchmark
36 | public void deleteBatch(FullState state) throws Exception {
37 | state.getTangle().deleteBatch(state.getPairs());
38 | }
39 |
40 | @Benchmark
41 | public void fetchOneByOne(FullState state) throws Exception {
42 | for (Pair> pair : state.getPairs()) {
43 | state.getTangle().load(pair.hi, pair.low);
44 | }
45 | }
46 |
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/benchmarks/dbbenchmark/states/DbState.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.benchmarks.dbbenchmark.states;
2 |
3 | import com.iota.iri.TransactionTestUtils;
4 | import com.iota.iri.conf.BaseIotaConfig;
5 | import com.iota.iri.controllers.TransactionViewModel;
6 | import com.iota.iri.model.persistables.Transaction;
7 | import com.iota.iri.storage.PersistenceProvider;
8 | import com.iota.iri.storage.Tangle;
9 | import com.iota.iri.storage.rocksDB.RocksDBPersistenceProvider;
10 | import org.apache.commons.io.FileUtils;
11 | import org.openjdk.jmh.annotations.Param;
12 | import org.openjdk.jmh.annotations.Scope;
13 | import org.openjdk.jmh.annotations.State;
14 |
15 | import java.io.File;
16 | import java.util.ArrayList;
17 | import java.util.Collections;
18 | import java.util.List;
19 |
20 | @State(Scope.Benchmark)
21 | public abstract class DbState {
22 | private final File dbFolder = new File("db-bench");
23 | private final File logFolder = new File("db-log-bench");
24 |
25 | private Tangle tangle;
26 | private List transactions;
27 |
28 | @Param({"10", "100", "500", "1000", "3000"})
29 | private int numTxsToTest;
30 |
31 |
32 | public void setup() throws Exception {
33 | System.out.println("-----------------------trial setup--------------------------------");
34 | boolean mkdirs = dbFolder.mkdirs();
35 | if (!mkdirs) {
36 | throw new IllegalStateException("db didn't start with a clean slate. Please delete "
37 | + dbFolder.getAbsolutePath());
38 | }
39 | logFolder.mkdirs();
40 | PersistenceProvider dbProvider = new RocksDBPersistenceProvider(dbFolder.getPath(), logFolder.getPath(),
41 | BaseIotaConfig.Defaults.DB_CACHE_SIZE);
42 | dbProvider.init();
43 | tangle = new Tangle();
44 | tangle.addPersistenceProvider(dbProvider);
45 | String trytes = "";
46 | System.out.println("numTxsToTest = [" + numTxsToTest + "]");
47 | transactions = new ArrayList<>(numTxsToTest);
48 | for (int i = 0; i < numTxsToTest; i++) {
49 | trytes = TransactionTestUtils.nextWord(trytes);
50 | TransactionViewModel tvm = TransactionTestUtils.createTransactionWithTrytes(trytes);
51 | transactions.add(tvm);
52 | }
53 | transactions = Collections.unmodifiableList(transactions);
54 | }
55 |
56 | public void teardown() throws Exception {
57 | System.out.println("-----------------------trial teardown--------------------------------");
58 | tangle.shutdown();
59 | FileUtils.forceDelete(dbFolder);
60 | FileUtils.forceDelete(logFolder);
61 | }
62 |
63 | public void clearDb() throws Exception {
64 | System.out.println("-----------------------iteration teardown--------------------------------");
65 | tangle.clearColumn(Transaction.class);
66 | tangle.clearMetadata(Transaction.class);
67 | }
68 |
69 | public Tangle getTangle() {
70 | return tangle;
71 | }
72 |
73 | public List getTransactions() {
74 | return transactions;
75 | }
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/benchmarks/dbbenchmark/states/EmptyState.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.benchmarks.dbbenchmark.states;
2 |
3 | import org.openjdk.jmh.annotations.*;
4 |
5 | @State(Scope.Benchmark)
6 | public class EmptyState extends DbState {
7 |
8 | @Override
9 | @Setup(Level.Trial)
10 | public void setup() throws Exception {
11 | super.setup();
12 | }
13 |
14 | @Override
15 | @TearDown(Level.Trial)
16 | public void teardown() throws Exception {
17 | super.teardown();
18 | }
19 |
20 | @Override
21 | @TearDown(Level.Iteration)
22 | public void clearDb() throws Exception {
23 | super.clearDb();
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/benchmarks/dbbenchmark/states/FullState.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.benchmarks.dbbenchmark.states;
2 |
3 | import com.iota.iri.controllers.TransactionViewModel;
4 | import com.iota.iri.model.persistables.Transaction;
5 | import com.iota.iri.storage.Indexable;
6 | import com.iota.iri.storage.Persistable;
7 | import com.iota.iri.utils.Pair;
8 | import org.openjdk.jmh.annotations.*;
9 |
10 | import java.util.Collections;
11 | import java.util.List;
12 | import java.util.stream.Collectors;
13 |
14 | @State(Scope.Benchmark)
15 | public class FullState extends DbState {
16 |
17 | private List>> pairs;
18 |
19 | @Override
20 | @Setup(Level.Trial)
21 | public void setup() throws Exception {
22 | super.setup();
23 | pairs = getTransactions().stream()
24 | .map(tvm -> new Pair<>((Indexable) tvm.getHash(), Transaction.class))
25 | .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
26 |
27 | }
28 |
29 | @Override
30 | @TearDown(Level.Trial)
31 | public void teardown() throws Exception {
32 | super.teardown();
33 | }
34 |
35 | @Override
36 | @TearDown(Level.Iteration)
37 | public void clearDb() throws Exception {
38 | super.clearDb();
39 | }
40 |
41 | @Setup(Level.Iteration)
42 | public void populateDb() throws Exception {
43 | System.out.println("-----------------------iteration setup--------------------------------");
44 | for (TransactionViewModel tvm : getTransactions()) {
45 | tvm.store(getTangle());
46 | }
47 | }
48 |
49 | public List>> getPairs() {
50 | return pairs;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/controllers/BundleViewModelTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.controllers;
2 |
3 | import com.iota.iri.storage.Tangle;
4 | import com.iota.iri.storage.rocksDB.RocksDBPersistenceProvider;
5 | import org.junit.After;
6 | import org.junit.Before;
7 | import org.junit.Test;
8 | import org.junit.rules.TemporaryFolder;
9 |
10 | /**
11 | * Created by paul on 5/2/17.
12 | */
13 | public class BundleViewModelTest {
14 | private static final TemporaryFolder dbFolder = new TemporaryFolder();
15 | private static final TemporaryFolder logFolder = new TemporaryFolder();
16 | private static Tangle tangle = new Tangle();
17 |
18 | @Before
19 | public void setUp() throws Exception {
20 | dbFolder.create();
21 | logFolder.create();
22 | RocksDBPersistenceProvider rocksDBPersistenceProvider;
23 | rocksDBPersistenceProvider = new RocksDBPersistenceProvider(dbFolder.getRoot().getAbsolutePath(),
24 | logFolder.getRoot().getAbsolutePath(),1000);
25 | tangle.addPersistenceProvider(rocksDBPersistenceProvider);
26 | tangle.init();
27 |
28 | }
29 |
30 | @After
31 | public void tearDown() throws Exception {
32 | tangle.shutdown();
33 | dbFolder.delete();
34 | logFolder.delete();
35 | }
36 |
37 | @Test
38 | public void quietFromHash() throws Exception {
39 |
40 | }
41 |
42 | @Test
43 | public void fromHash() throws Exception {
44 |
45 | }
46 |
47 | @Test
48 | public void getTransactionViewModels() throws Exception {
49 |
50 | }
51 |
52 | @Test
53 | public void quietGetTail() throws Exception {
54 |
55 | }
56 |
57 | @Test
58 | public void getTail() throws Exception {
59 |
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/controllers/TagViewModelTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.controllers;
2 |
3 | import org.junit.After;
4 | import org.junit.Before;
5 | import org.junit.Test;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | /**
10 | * Created by paul on 5/2/17.
11 | */
12 | public class TagViewModelTest {
13 | @Before
14 | public void setUp() throws Exception {
15 |
16 | }
17 |
18 | @After
19 | public void tearDown() throws Exception {
20 |
21 | }
22 |
23 | @Test
24 | public void getHash() throws Exception {
25 |
26 | }
27 |
28 | @Test
29 | public void getTransactionHashes() throws Exception {
30 |
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/controllers/TransactionRequesterTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.controllers;
2 |
3 | import com.iota.iri.model.Hash;
4 | import com.iota.iri.network.TransactionRequester;
5 | import com.iota.iri.storage.Tangle;
6 | import com.iota.iri.zmq.MessageQ;
7 | import org.junit.After;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Created by paul on 5/2/17.
15 | */
16 | public class TransactionRequesterTest {
17 | private static Tangle tangle = new Tangle();
18 | private MessageQ mq;
19 |
20 | @Before
21 | public void setUp() throws Exception {
22 |
23 | }
24 |
25 | @After
26 | public void tearDown() throws Exception {
27 |
28 | }
29 |
30 | @Test
31 | public void init() throws Exception {
32 |
33 | }
34 |
35 | @Test
36 | public void rescanTransactionsToRequest() throws Exception {
37 |
38 | }
39 |
40 | @Test
41 | public void getRequestedTransactions() throws Exception {
42 |
43 | }
44 |
45 | @Test
46 | public void numberOfTransactionsToRequest() throws Exception {
47 |
48 | }
49 |
50 | @Test
51 | public void clearTransactionRequest() throws Exception {
52 |
53 | }
54 |
55 | @Test
56 | public void requestTransaction() throws Exception {
57 |
58 | }
59 |
60 | @Test
61 | public void transactionToRequest() throws Exception {
62 |
63 | }
64 |
65 | @Test
66 | public void checkSolidity() throws Exception {
67 |
68 | }
69 |
70 | @Test
71 | public void instance() throws Exception {
72 |
73 | }
74 |
75 | @Test
76 | public void capacityLimited() throws Exception {
77 | TransactionRequester txReq = new TransactionRequester(tangle, mq);
78 | int capacity = TransactionRequester.MAX_TX_REQ_QUEUE_SIZE;
79 | //fill tips list
80 | for (int i = 0; i < capacity * 2 ; i++) {
81 | Hash hash = TransactionViewModelTest.getRandomTransactionHash();
82 | txReq.requestTransaction(hash);
83 | }
84 | //check that limit wasn't breached
85 | assertEquals(capacity, txReq.numberOfTransactionsToRequest());
86 | }
87 |
88 | @Test
89 | public void queueIsEmptyAfterCallingClearQueue() throws Exception {
90 | final int txCount = 60;
91 | TransactionRequester txReq = new TransactionRequester(tangle, mq);
92 |
93 | //fill tips list
94 | for (int i = 0; i < txCount; i++) {
95 | Hash hash = TransactionViewModelTest.getRandomTransactionHash();
96 | txReq.requestTransaction(hash);
97 | }
98 |
99 | assertEquals(txCount, txReq.numberOfTransactionsToRequest());
100 |
101 | txReq.clearQueue();
102 |
103 | assertEquals(0, txReq.numberOfTransactionsToRequest());
104 | }
105 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/model/persistables/TransactionTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.model.persistables;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.util.Random;
6 |
7 | import com.iota.iri.controllers.TransactionViewModel;
8 | import com.iota.iri.utils.Converter;
9 |
10 | import org.junit.Test;
11 |
12 | public class TransactionTest {
13 | private static final Random seed = new Random();
14 |
15 | @Test
16 | public void metadataParsedCorrectlyInHappyFlow() throws Exception {
17 | Transaction tx = getRandomTransaction();
18 |
19 | Transaction fromMetaData = new Transaction();
20 | byte[] bytes = tx.metadata();
21 | fromMetaData.readMetadata(bytes);
22 |
23 | assertEquals(tx.address, fromMetaData.address);
24 | assertEquals(tx.bundle, fromMetaData.bundle);
25 | assertEquals(tx.trunk, fromMetaData.trunk);
26 | assertEquals(tx.branch, fromMetaData.branch);
27 | assertEquals(tx.obsoleteTag, fromMetaData.obsoleteTag);
28 | assertEquals(tx.value, fromMetaData.value);
29 | assertEquals(tx.currentIndex, fromMetaData.currentIndex);
30 | assertEquals(tx.lastIndex, fromMetaData.lastIndex);
31 | assertEquals(tx.timestamp, fromMetaData.timestamp);
32 |
33 | assertEquals(tx.tag, fromMetaData.tag);
34 | assertEquals(tx.attachmentTimestamp, fromMetaData.attachmentTimestamp);
35 | assertEquals(tx.attachmentTimestampLowerBound, fromMetaData.attachmentTimestampLowerBound);
36 | assertEquals(tx.attachmentTimestampUpperBound, fromMetaData.attachmentTimestampUpperBound);
37 |
38 | assertEquals(tx.validity, fromMetaData.validity);
39 | assertEquals(tx.type, fromMetaData.type);
40 | assertEquals(tx.arrivalTime, fromMetaData.arrivalTime);
41 | assertEquals(tx.height, fromMetaData.height);
42 | assertEquals(tx.solidificationTime, fromMetaData.solidificationTime);
43 |
44 | assertEquals(tx.solid, fromMetaData.solid);
45 | }
46 |
47 | private Transaction getRandomTransaction() {
48 | Transaction transaction = new Transaction();
49 |
50 | byte[] trits = new byte[TransactionViewModel.SIGNATURE_MESSAGE_FRAGMENT_TRINARY_SIZE];
51 | for(int i = 0; i < trits.length; i++) {
52 | trits[i] = (byte) (seed.nextInt(3) - 1);
53 | }
54 |
55 | transaction.bytes = Converter.allocateBytesForTrits(trits.length);
56 | Converter.bytes(trits, 0, transaction.bytes, 0, trits.length);
57 | transaction.readMetadata(transaction.bytes);
58 | return transaction;
59 | }
60 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/network/UDPNeighborTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.network;
2 |
3 | import org.junit.Test;
4 |
5 | import java.net.InetSocketAddress;
6 | import java.net.SocketAddress;
7 |
8 | import static org.junit.Assert.assertFalse;
9 | import static org.junit.Assert.assertTrue;
10 |
11 | public class UDPNeighborTest {
12 |
13 | private final UDPNeighbor neighbor = new UDPNeighbor(address("localhost", 42), null, false);
14 |
15 | @Test
16 | public void sameIpWhenMatchesThenTrue() {
17 | assertTrue("expected match", neighbor.matches(address("localhost", 42)));
18 | assertTrue("expected match", neighbor.matches(address("localhost", 666)));
19 | assertTrue("expected match", neighbor.matches(address("127.0.0.1", 42)));
20 | assertTrue("expected match", neighbor.matches(address("127.0.0.1", 666)));
21 | }
22 |
23 | @Test
24 | public void differentIpWhenMatchesThenFalse() {
25 | assertFalse("expected no match", neighbor.matches(address("foo.bar.com", 42)));
26 | assertFalse("expected no match", neighbor.matches(address("8.8.8.8", 42)));
27 | assertFalse("expected no match", neighbor.matches(null));
28 | assertFalse("expected no match", neighbor.matches(new SocketAddress() {}));
29 | }
30 |
31 | private InetSocketAddress address(String hostOrIp, int port) {
32 | return new InetSocketAddress(hostOrIp, port);
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/service/tipselection/impl/EntryPointSelectorGenesisImplTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.service.tipselection.impl;
2 |
3 | import com.iota.iri.model.Hash;
4 | import com.iota.iri.service.tipselection.EntryPointSelector;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | public class EntryPointSelectorGenesisImplTest {
9 |
10 | @Test
11 | public void testEntryPointBWithTangleData() throws Exception {
12 |
13 | EntryPointSelector entryPointSelector = new EntryPointSelectorGenesisImpl();
14 | Hash entryPoint = entryPointSelector.getEntryPoint();
15 |
16 | Assert.assertEquals("The entry point should be the milestone in the Tangle", Hash.NULL_HASH, entryPoint);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/storage/TangleTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.storage;
2 |
3 | import com.iota.iri.controllers.TransactionViewModel;
4 | import com.iota.iri.crypto.SpongeFactory;
5 | import com.iota.iri.model.Hash;
6 | import com.iota.iri.model.TransactionHash;
7 | import com.iota.iri.model.persistables.Tag;
8 | import com.iota.iri.storage.rocksDB.RocksDBPersistenceProvider;
9 | import com.iota.iri.utils.Converter;
10 | import org.junit.After;
11 | import org.junit.Assert;
12 | import org.junit.Before;
13 | import org.junit.Test;
14 | import org.junit.rules.TemporaryFolder;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 |
18 | import java.util.*;
19 |
20 | public class TangleTest {
21 | private final TemporaryFolder dbFolder = new TemporaryFolder();
22 | private final TemporaryFolder logFolder = new TemporaryFolder();
23 | private Tangle tangle = new Tangle();
24 |
25 | private static final Random seed = new Random();
26 | Logger log = LoggerFactory.getLogger(Tangle.class);
27 |
28 | @Before
29 | public void setUp() throws Exception {
30 | dbFolder.create();
31 | logFolder.create();
32 | RocksDBPersistenceProvider rocksDBPersistenceProvider;
33 | rocksDBPersistenceProvider = new RocksDBPersistenceProvider(dbFolder.getRoot().getAbsolutePath(),
34 | logFolder.getRoot().getAbsolutePath(),1000);
35 | tangle.addPersistenceProvider(rocksDBPersistenceProvider);
36 | tangle.init();
37 | }
38 |
39 | @After
40 | public void tearDown() throws Exception {
41 | tangle.shutdown();
42 | }
43 |
44 | @Test
45 | public void save() throws Exception {
46 | }
47 |
48 | @Test
49 | public void getKeysStartingWithValue() throws Exception {
50 | byte[] trits = getRandomTransactionTrits();
51 | TransactionViewModel transactionViewModel = new TransactionViewModel(trits, TransactionHash.calculate(SpongeFactory.Mode.CURLP81, trits));
52 | transactionViewModel.store(tangle);
53 | Set tag = tangle.keysStartingWith(Tag.class, Arrays.copyOf(transactionViewModel.getTagValue().bytes(), 15));
54 | Assert.assertNotEquals(tag.size(), 0);
55 | }
56 |
57 | @Test
58 | public void get() throws Exception {
59 | }
60 |
61 | public static byte[] getRandomTransactionTrits() {
62 | byte[] out = new byte[TransactionViewModel.TRINARY_SIZE];
63 |
64 | for(int i = 0; i < out.length; i++) {
65 | out[i] = (byte) (seed.nextInt(3) - 1);
66 | }
67 |
68 | return out;
69 | }
70 |
71 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/utils/BoundedHashSetTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | import com.iota.iri.utils.collections.impl.BoundedHashSet;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 |
7 | import java.util.Arrays;
8 | import java.util.HashSet;
9 | import java.util.List;
10 |
11 | public class BoundedHashSetTest {
12 |
13 | @Test
14 | public void createBoundedHashSetWithCollectionTest() {
15 | List list = Arrays.asList(1, 2 ,3, 4, 5, 6);
16 | BoundedHashSet boundedSet = new BoundedHashSet<>(list, 4);
17 | Assert.assertEquals(new HashSet<>(Arrays.asList(1, 2, 3, 4)), boundedSet);
18 | }
19 |
20 | @Test
21 | public void testAdd() {
22 | BoundedHashSet boundedSet = new BoundedHashSet<>(3);
23 | Assert.assertTrue("can't add to unfull set", boundedSet.add(1));
24 | Assert.assertTrue("can't add to unfull set", boundedSet.add(2));
25 | Assert.assertTrue("can't add to unfull set", boundedSet.add(3));
26 | Assert.assertFalse("can add to full set", boundedSet.add(4));
27 | Assert.assertEquals("bounded set doesn't have expected contents",
28 | new HashSet<>(Arrays.asList(1, 2, 3)), boundedSet);
29 | }
30 |
31 | @Test
32 | public void testAddAll() {
33 | BoundedHashSet boundedSet = new BoundedHashSet<>(3);
34 | Assert.assertTrue("set did not change after add", boundedSet.addAll(Arrays.asList(5, 6, 7, 8, 9)));
35 | Assert.assertEquals("bounded set doesn't have expected contents",
36 | new HashSet<>(Arrays.asList(5, 6, 7)), boundedSet);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/utils/ConverterTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | public class ConverterTest {
4 |
5 |
6 | }
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/utils/TestSerializer.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils;
2 |
3 | import java.nio.ByteBuffer;
4 |
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | public class TestSerializer {
9 |
10 | @Test
11 | public void testSerEndian() {
12 | final long[] ltestvec = {0L, 1L, Long.MAX_VALUE, 123456789L};
13 | final int[] itestvec = {0, 1, Integer.MAX_VALUE, 123456789};
14 |
15 | for(long l : ltestvec)
16 | Assert.assertArrayEquals(Serializer.serialize(l), bbSerialize(l));
17 |
18 | for(int i : itestvec)
19 | Assert.assertArrayEquals(Serializer.serialize(i), bbSerialize(i));
20 |
21 | }
22 |
23 | // reference for original bytebuffer code
24 | public static byte[] bbSerialize(Long value) {
25 | ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
26 | buffer.putLong(value);
27 | return buffer.array();
28 | }
29 | public static byte[] bbSerialize(int integer) {
30 | ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
31 | buffer.putInt(integer);
32 | return buffer.array();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/com/iota/iri/utils/collections/impl/BoundedSetWrapperTest.java:
--------------------------------------------------------------------------------
1 | package com.iota.iri.utils.collections.impl;
2 |
3 | import com.iota.iri.utils.collections.interfaces.BoundedSet;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 | import org.mockito.internal.util.collections.Sets;
7 |
8 | import java.util.Arrays;
9 | import java.util.LinkedHashSet;
10 | import java.util.Set;
11 |
12 | public class BoundedSetWrapperTest {
13 |
14 | @Test(expected = IllegalArgumentException.class)
15 | public void createSetWithException() {
16 | Set set = Sets.newSet(1, 2, 3, 4, 5, 6);
17 | new BoundedSetWrapper<>(set, 4);
18 | }
19 |
20 | @Test
21 | public void createSetAndAssertEquals() {
22 | Set set = Sets.newSet(1, 2, 3, 4, 5, 6);
23 | BoundedSet boundedSetWrapper = new BoundedSetWrapper<>(set, 6);
24 | Assert.assertEquals("sets should be equal", set, boundedSetWrapper);
25 |
26 | }
27 |
28 | @Test
29 | public void testAdd() {
30 | BoundedSet boundedSet = new BoundedSetWrapper<>(new LinkedHashSet<>(), 3);
31 | Assert.assertTrue("can't add", boundedSet.add(1));
32 | Assert.assertTrue("can't add", boundedSet.add(2));
33 | Assert.assertTrue("can't add", boundedSet.add(3));
34 | Assert.assertTrue("can't add", boundedSet.add(4));
35 | Assert.assertEquals("bounded set doesn't have expected contents",
36 | Sets.newSet(2, 3, 4), boundedSet);
37 | }
38 |
39 | @Test(expected = IllegalArgumentException.class)
40 | public void testAddAll() {
41 | BoundedSet boundedSet = new BoundedSetWrapper<>(new LinkedHashSet<>(), 3);
42 | boundedSet.addAll(Arrays.asList(5, 6, 7, 8, 9));
43 | }
44 |
45 | }
--------------------------------------------------------------------------------