diff --git a/README.md b/README.md index fb1bd251..157fa5a6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Special thanks to all of the [IOTA Contributors](https://github.com/iotaledger/i ## Developers - Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. -- Please read the [helix-1.0-specifications](https://github.com/HelixNetwork/helix-specs/blob/master/specs/helix-1.0.md) before contributing. +- Please read the [helix-1.0-specifications](https://github.com/HelixNetwork/helix-specs/tree/master/specs/1.0) before contributing. ## Installing Make sure you have [**Maven**](https://maven.apache.org/) and [**Java 8**](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) installed on your computer. diff --git a/src/main/java/net/helix/hlx/controllers/AddressViewModel.java b/src/main/java/net/helix/hlx/controllers/AddressViewModel.java index de4f5750..113a545b 100644 --- a/src/main/java/net/helix/hlx/controllers/AddressViewModel.java +++ b/src/main/java/net/helix/hlx/controllers/AddressViewModel.java @@ -1,6 +1,7 @@ package net.helix.hlx.controllers; import net.helix.hlx.model.Hash; +import net.helix.hlx.model.AddressHash; import net.helix.hlx.model.persistables.Address; import net.helix.hlx.storage.Indexable; import net.helix.hlx.storage.Persistable; @@ -107,7 +108,7 @@ public void delete(Tangle tangle) throws Exception { * @return AddressViewModel */ public static AddressViewModel first(Tangle tangle) throws Exception { - Pair bundlePair = tangle.getFirst(Address.class, Hash.class); + Pair bundlePair = tangle.getFirst(Address.class, AddressHash.class); if(bundlePair != null && bundlePair.hi != null) { return new AddressViewModel((Address) bundlePair.hi, (Hash) bundlePair.low); } diff --git a/src/main/java/net/helix/hlx/controllers/ApproveeViewModel.java b/src/main/java/net/helix/hlx/controllers/ApproveeViewModel.java index ae8de482..e37cd1ba 100644 --- a/src/main/java/net/helix/hlx/controllers/ApproveeViewModel.java +++ b/src/main/java/net/helix/hlx/controllers/ApproveeViewModel.java @@ -1,6 +1,7 @@ package net.helix.hlx.controllers; import net.helix.hlx.model.Hash; +import net.helix.hlx.model.TransactionHash; import net.helix.hlx.model.persistables.Approvee; import net.helix.hlx.storage.Indexable; import net.helix.hlx.storage.Persistable; @@ -121,7 +122,7 @@ public void delete(Tangle tangle) throws Exception { * @return ApproveeViewModel */ public static ApproveeViewModel first(Tangle tangle) throws Exception { - Pair bundlePair = tangle.getFirst(Approvee.class, Hash.class); + Pair bundlePair = tangle.getFirst(Approvee.class, TransactionHash.class); if(bundlePair != null && bundlePair.hi != null) { return new ApproveeViewModel((Approvee) bundlePair.hi, (Hash) bundlePair.low); } diff --git a/src/main/java/net/helix/hlx/controllers/BundleViewModel.java b/src/main/java/net/helix/hlx/controllers/BundleViewModel.java index 501c50f3..7d35e4fd 100644 --- a/src/main/java/net/helix/hlx/controllers/BundleViewModel.java +++ b/src/main/java/net/helix/hlx/controllers/BundleViewModel.java @@ -1,6 +1,7 @@ package net.helix.hlx.controllers; import net.helix.hlx.model.Hash; +import net.helix.hlx.model.BundleHash; import net.helix.hlx.model.persistables.Bundle; import net.helix.hlx.storage.Indexable; import net.helix.hlx.storage.Persistable; @@ -129,7 +130,7 @@ public void delete(Tangle tangle) throws Exception { * @return bundleViewModel */ public static BundleViewModel first(Tangle tangle) throws Exception { - Pair bundlePair = tangle.getFirst(Bundle.class, Hash.class); + Pair bundlePair = tangle.getFirst(Bundle.class, BundleHash.class); if(bundlePair != null && bundlePair.hi != null) { return new BundleViewModel((Bundle) bundlePair.hi, (Hash) bundlePair.low); } diff --git a/src/main/java/net/helix/hlx/controllers/TagViewModel.java b/src/main/java/net/helix/hlx/controllers/TagViewModel.java index c73dcfd6..5809e745 100644 --- a/src/main/java/net/helix/hlx/controllers/TagViewModel.java +++ b/src/main/java/net/helix/hlx/controllers/TagViewModel.java @@ -1,6 +1,7 @@ package net.helix.hlx.controllers; import net.helix.hlx.model.Hash; +import net.helix.hlx.model.TagHash; import net.helix.hlx.model.persistables.Tag; import net.helix.hlx.storage.Indexable; import net.helix.hlx.storage.Persistable; @@ -34,6 +35,10 @@ public static TagViewModel load(Tangle tangle, Indexable hash) throws Exception return load(tangle, hash, Tag.class); } + public static TagViewModel loadBundleNonce(Tangle tangle, Indexable hash) throws Exception { + return load(tangle, hash, net.helix.hlx.model.persistables.BundleNonce.class); + } + public static Map.Entry getEntry(Hash hash, Hash hashToMerge) throws Exception { Tag hashes = new Tag(); hashes.set.add(hashToMerge); @@ -64,7 +69,7 @@ public void delete(Tangle tangle) throws Exception { tangle.delete(Tag.class,hash); } public static TagViewModel first(Tangle tangle) throws Exception { - Pair bundlePair = tangle.getFirst(Tag.class, Hash.class); + Pair bundlePair = tangle.getFirst(Tag.class, TagHash.class); if(bundlePair != null && bundlePair.hi != null) { return new TagViewModel((Tag) bundlePair.hi, (Hash) bundlePair.low); } diff --git a/src/main/java/net/helix/hlx/controllers/TransactionViewModel.java b/src/main/java/net/helix/hlx/controllers/TransactionViewModel.java index 463e1187..07c4f2aa 100644 --- a/src/main/java/net/helix/hlx/controllers/TransactionViewModel.java +++ b/src/main/java/net/helix/hlx/controllers/TransactionViewModel.java @@ -8,7 +8,6 @@ import net.helix.hlx.storage.Tangle; import net.helix.hlx.utils.Converter; import net.helix.hlx.utils.Pair; -import org.bouncycastle.util.encoders.Hex; import java.util.*; @@ -252,7 +251,7 @@ public List> getSaveBatch() throws Exception { * @return TransactionViewModel */ public static TransactionViewModel first(Tangle tangle) throws Exception { - Pair transactionPair = tangle.getFirst(Transaction.class, Hash.class); + Pair transactionPair = tangle.getFirst(Transaction.class, TransactionHash.class); if(transactionPair != null && transactionPair.hi != null) { return new TransactionViewModel((Transaction) transactionPair.hi, (Hash) transactionPair.low); } @@ -298,6 +297,20 @@ public boolean store(Tangle tangle, Snapshot initialSnapshot) throws Exception { return tangle.saveBatch(batch); } + /** + * Creates a copy of the underlying {@link Transaction} object. + * + * @return the transaction object + */ + public Transaction getTransaction() { + Transaction t = new Transaction(); + + //if the supplied array to the call != null the transaction bytes are copied over from the buffer. + t.read(getBytes()); + t.readMetadata(transaction.metadata()); + return t; + } + /** * Gets the {@link ApproveeViewModel} of a {@link Transaction}. If the current {@link ApproveeViewModel} is null, a * new one is created using the transaction {@link Hash} identifier. @@ -452,7 +465,7 @@ public Hash getBranchTransactionHash() { */ public Hash getTagValue() { if(transaction.tag == null) { - transaction.tag = HashFactory.TAG.create(getBytes(), TAG_OFFSET); + transaction.tag = HashFactory.TAG.create(getBytes(), TAG_OFFSET, TAG_SIZE); } return transaction.tag; } diff --git a/src/main/java/net/helix/hlx/model/AbstractHash.java b/src/main/java/net/helix/hlx/model/AbstractHash.java index fea38901..13e2760f 100644 --- a/src/main/java/net/helix/hlx/model/AbstractHash.java +++ b/src/main/java/net/helix/hlx/model/AbstractHash.java @@ -1,55 +1,93 @@ package net.helix.hlx.model; +import java.io.Serializable; +import java.util.Arrays; + +import org.bouncycastle.util.encoders.Hex; + import net.helix.hlx.utils.Converter; import net.helix.hlx.model.persistables.Transaction; -import net.helix.hlx.model.safe.ByteSafe; import net.helix.hlx.storage.Indexable; -import org.bouncycastle.util.encoders.Hex; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Objects; - -public abstract class AbstractHash implements Hash, Serializable { +/** + * Base implementation of a hash object. + */ +public abstract class AbstractHash implements Hash, Serializable { + private byte[] data; + private Integer hashCode; private final Object lock = new Object(); - private ByteSafe byteSafe; /** - * AbstractHash constructor for byte array with offset. - * @param source byte array - * @param sourceOffset offset length - * @param sourceSize length of byte array + * Empty Constructor for a placeholder hash identifier object. Creates a hash identifier object with no properties. + */ + public AbstractHash() { + } + + /** + * Constructor for a hash object using a byte source array. + * + * @param source A byte array containing the source information in byte format + * @param sourceOffset The offset defining the start point for the hash object in the source + * @param sourceSize The size of the hash object that will be created */ public AbstractHash(byte[] source, int sourceOffset, int sourceSize) { - byte[] dest = new byte[SIZE_IN_BYTES]; - System.arraycopy(source, sourceOffset, dest, 0, sourceSize - sourceOffset > source.length ? source.length - sourceOffset : sourceSize); - this.byteSafe = new ByteSafe(dest); + read(source, sourceOffset, sourceSize + sourceOffset > source.length ? source.length - sourceOffset : sourceSize); } /** - * Private method for reading in the byte array. - * @param src byte array - * @throws IllegalStateException in case bytes are already initialized. + * Assigns the input byte data to the hash object. Each hash object can only be initialized with data + * once. If the byte array is not null, an IllegalStateException is thrown. + * + * @param source A byte array containing the source bytes */ - private void fullRead(byte[] src) { - if (src != null) { + @Override + public void read(byte[] source) { + if (source != null) { synchronized (lock) { - if (byteSafe != null) { + if (data != null) { throw new IllegalStateException("I cannot be initialized with data twice."); } - byte[] dest = new byte[SIZE_IN_BYTES]; - System.arraycopy(src, 0, dest, 0, Math.min(dest.length, src.length)); - byteSafe = new ByteSafe(dest); + read(source, 0, source.length); } } } /** - * Counting number of zeros in a byte array + * Private method for reading in the byte array. + * + * @param source byte array + * @param offset The offset defining the start point for the hash object in the source + * @param length The length of the hash object that will be created + * @throws IllegalStateException in case bytes are already initialized + */ + private void read(byte[] source, int offset, int length) { + data = new byte[SIZE_IN_BYTES]; + System.arraycopy(source, offset, data, 0, Math.min(data.length, length)); + hashCode = Arrays.hashCode(data); + } + + /** + * Checks if the hash object is storing a byte array. If there + * is no byte array present, a NullPointerException will be thrown. + * + * @return The stored byte array containing the hash values + */ + @Override + public byte[] bytes() { + if (data == null) { + throw new NullPointerException("No bytes initialized, please use read(byte[]) to read in the byte array"); + } + return data; + } + + /** + * Counting number of zeros in a byte array. + * * @return zeros int */ + @Override public int trailingZeros() { final byte[] bytes = bytes(); int index = SIZE_IN_BYTES; @@ -61,9 +99,11 @@ public int trailingZeros() { } /** - * Counting number of zeros in a byte array + * Counting number of zeros in a byte array. + * * @return zeros int */ + @Override public int leadingZeros() { final byte[] bytes = bytes(); int index = 0; @@ -77,7 +117,9 @@ public int leadingZeros() { /** - * Check Equality of hash and object o + * Check equality of hash and object o. + * + * @param o the reference object with which to compare * @return boolean equality */ @Override @@ -93,40 +135,24 @@ public boolean equals(Object o) { } /** - * Get hash code of bytes from byteSafe. - * @return boolean equality + * Get hash code of bytes. + * + * @return a hash code value for this object */ @Override public int hashCode() { bytes(); - return byteSafe.getHashcode(); - } - - /** - * Get bytes. - * @return byte[] bytes - */ - public byte[] bytes() { - ByteSafe safe = byteSafe; - if (safe == null) { - Objects.requireNonNull(byteSafe, "No bytes initialized, Please use fullRead(byte[]) to read in the byte array"); - } - return safe.getData(); + return hashCode; } /** - * Convert to hex string + * Convert to hex string. + * * @return string string in hex representation */ - public String toString() { return Hex.toHexString(bytes()); } - - /** - * Reading byte array. @see #fullRead(byte[]) - * @param src byte array - */ @Override - public void read(byte[] src) { - fullRead(src); + public String toString() { + return Hex.toHexString(bytes()); } @Override @@ -141,6 +167,7 @@ public Indexable decremented() { /** * Get difference between Hash and Indexable . Returns 0 if they are equal. + * * @param indexable * @return int difference */ diff --git a/src/main/java/net/helix/hlx/model/AddressHash.java b/src/main/java/net/helix/hlx/model/AddressHash.java index d09c2882..25ac63ae 100644 --- a/src/main/java/net/helix/hlx/model/AddressHash.java +++ b/src/main/java/net/helix/hlx/model/AddressHash.java @@ -1,6 +1,10 @@ package net.helix.hlx.model; public class AddressHash extends AbstractHash { + + public AddressHash() { + } + protected AddressHash(byte[] bytes, int offset, int sizeInBytes) { super(bytes, offset, sizeInBytes); } diff --git a/src/main/java/net/helix/hlx/model/BundleHash.java b/src/main/java/net/helix/hlx/model/BundleHash.java index b891f3a3..0731e991 100644 --- a/src/main/java/net/helix/hlx/model/BundleHash.java +++ b/src/main/java/net/helix/hlx/model/BundleHash.java @@ -1,6 +1,10 @@ package net.helix.hlx.model; public class BundleHash extends AbstractHash { + + public BundleHash() { + } + protected BundleHash(byte[] bytes, int offset, int sizeInBytes) { super(bytes, offset, sizeInBytes); } diff --git a/src/main/java/net/helix/hlx/model/BundleNonceHash.java b/src/main/java/net/helix/hlx/model/BundleNonceHash.java index 028f173e..4bd027e8 100644 --- a/src/main/java/net/helix/hlx/model/BundleNonceHash.java +++ b/src/main/java/net/helix/hlx/model/BundleNonceHash.java @@ -1,6 +1,10 @@ package net.helix.hlx.model; public class BundleNonceHash extends AbstractHash { + + public BundleNonceHash() { + } + protected BundleNonceHash(byte[] tagBytes, int offset, int tagSizeInBytes) { super(tagBytes, offset, tagSizeInBytes); } diff --git a/src/main/java/net/helix/hlx/model/Hash.java b/src/main/java/net/helix/hlx/model/Hash.java index 7aadb7bb..81b79bbd 100644 --- a/src/main/java/net/helix/hlx/model/Hash.java +++ b/src/main/java/net/helix/hlx/model/Hash.java @@ -2,7 +2,6 @@ import net.helix.hlx.crypto.Sha3; import net.helix.hlx.storage.Indexable; -//import net.helix.hlx.utils.Converter; /** @@ -11,6 +10,11 @@ * and the inner classes ByteSafe */ public interface Hash extends Indexable, HashId { + + /** + * Creates a null transaction hash with from a byte array of length {@value Sha3#HASH_LENGTH}. + * This is used as a reference hash for the genesis transaction. + */ Hash NULL_HASH = HashFactory.TRANSACTION.create(new byte[Sha3.HASH_LENGTH]); /** diff --git a/src/main/java/net/helix/hlx/model/HashFactory.java b/src/main/java/net/helix/hlx/model/HashFactory.java index 0ce5d80b..0c952c94 100644 --- a/src/main/java/net/helix/hlx/model/HashFactory.java +++ b/src/main/java/net/helix/hlx/model/HashFactory.java @@ -79,7 +79,7 @@ public Hash create(byte[] source) { * @return the hash of the correct type */ public Hash create(Class modelClass, byte[] source) { - return create(modelClass, source, 0, AbstractHash.SIZE_IN_BYTES); + return create(modelClass, source, 0, Hash.SIZE_IN_BYTES); } /** diff --git a/src/main/java/net/helix/hlx/model/TagHash.java b/src/main/java/net/helix/hlx/model/TagHash.java index 5f0c687a..0851f0e7 100644 --- a/src/main/java/net/helix/hlx/model/TagHash.java +++ b/src/main/java/net/helix/hlx/model/TagHash.java @@ -1,6 +1,10 @@ package net.helix.hlx.model; public class TagHash extends AbstractHash { + + public TagHash() { + } + protected TagHash(byte[] tagBytes, int offset, int tagSizeInBytes) { super(tagBytes, offset, tagSizeInBytes); } diff --git a/src/main/java/net/helix/hlx/model/TransactionHash.java b/src/main/java/net/helix/hlx/model/TransactionHash.java index d16ce067..f77281dd 100644 --- a/src/main/java/net/helix/hlx/model/TransactionHash.java +++ b/src/main/java/net/helix/hlx/model/TransactionHash.java @@ -1,12 +1,14 @@ package net.helix.hlx.model; -import net.helix.hlx.controllers.TransactionViewModel; import net.helix.hlx.crypto.Sponge; import net.helix.hlx.crypto.SpongeFactory; -import net.helix.hlx.utils.FastByteComparisons; import org.bouncycastle.util.encoders.Hex; public class TransactionHash extends AbstractHash { + + public TransactionHash() { + } + protected TransactionHash(byte[] source, int offset, int sourceSize) { super(source, offset, sourceSize); } @@ -33,11 +35,9 @@ public static TransactionHash calculate(SpongeFactory.Mode mode, byte[] bytes) { // TODO: Always calculate the hash without exception. The extra exception for nullBytes is needed opposed to IRI, as their custom hash functions seem to map nullTrits to NULL_HASH. It is important for the nullBytes to hash to the NULL_HASH in order to have a solid entry point. public static TransactionHash calculate(final byte[] bytes, int offset, int length, final Sponge sha3) { byte[] hash = new byte[SIZE_IN_BYTES]; -// byte[] nullBytes = new byte[TransactionViewModel.SIZE]; sha3.reset(); sha3.absorb(bytes, offset, length); sha3.squeeze(hash, 0, SIZE_IN_BYTES); -// return (FastByteComparisons.compareTo(bytes,0, TransactionViewModel.SIZE, nullBytes, 0, TransactionViewModel.SIZE) == 0) ? (TransactionHash) NULL_HASH : (TransactionHash) HashFactory.TRANSACTION.create(hash, 0, SIZE_IN_BYTES); return (TransactionHash) HashFactory.TRANSACTION.create(hash, 0, SIZE_IN_BYTES); } diff --git a/src/main/java/net/helix/hlx/model/persistables/BundleNonce.java b/src/main/java/net/helix/hlx/model/persistables/BundleNonce.java index 1c5a67b2..d79ba185 100644 --- a/src/main/java/net/helix/hlx/model/persistables/BundleNonce.java +++ b/src/main/java/net/helix/hlx/model/persistables/BundleNonce.java @@ -2,9 +2,14 @@ import net.helix.hlx.model.Hash; -public class BundleNonce extends Hashes { - public BundleNonce(Hash hash) { set.add(hash); } +public class BundleNonce extends Tag { + + public BundleNonce(Hash hash) { + super(hash); + } + + // used by the persistence layer to instantiate the object + public BundleNonce() { + } - // used by the persistance layer to store the object - public BundleNonce() {} } diff --git a/src/main/java/net/helix/hlx/model/safe/ByteSafe.java b/src/main/java/net/helix/hlx/model/safe/ByteSafe.java deleted file mode 100644 index 4f8e78aa..00000000 --- a/src/main/java/net/helix/hlx/model/safe/ByteSafe.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.helix.hlx.model.safe; - -public class ByteSafe extends HashSafeObject { - public ByteSafe(byte[] bytes) { - super(bytes, "ByteSafe is attempted to be initialized with a null byte array"); - } -} diff --git a/src/main/java/net/helix/hlx/model/safe/HashSafeObject.java b/src/main/java/net/helix/hlx/model/safe/HashSafeObject.java deleted file mode 100644 index bff4712e..00000000 --- a/src/main/java/net/helix/hlx/model/safe/HashSafeObject.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.helix.hlx.model.safe; - -import java.util.Arrays; - -public class HashSafeObject extends SafeObject { - private Integer hashcode; - - public HashSafeObject(byte[] obj, String messageIfUnsafe) { - super(obj, messageIfUnsafe); - this.hashcode = Arrays.hashCode(getData()); - // TODO this.bytes = bytes; this.hashcode = Arrays.hashCode(bytes); ? - } - - /** - * Returns the hash code from the contained data - * @return the hashcode - */ - public Integer getHashcode() { - return hashcode; - } -} diff --git a/src/main/java/net/helix/hlx/model/safe/SafeObject.java b/src/main/java/net/helix/hlx/model/safe/SafeObject.java deleted file mode 100644 index 11ed01ab..00000000 --- a/src/main/java/net/helix/hlx/model/safe/SafeObject.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.helix.hlx.model.safe; - -import java.util.Objects; - -public class SafeObject { - byte[] safeObj; - - /** - * Creates an object which is verified during instantiation. - * @param obj the array of bytes we check against - * @param messageIfUnsafe The message we emit when it is not safe (inside an exception) - */ - SafeObject(byte[] obj, String messageIfUnsafe){ - this.safeObj = obj; - - checkSafe(messageIfUnsafe); - } - - /** - * This data is checked against its "save" conditions. - * @return the data this object guards - */ - public byte[] getData() { - return safeObj; - } - - protected void checkSafe(String messageIfUnsafe) { - Objects.requireNonNull(safeObj, messageIfUnsafe); - } -} diff --git a/src/main/java/net/helix/hlx/service/API.java b/src/main/java/net/helix/hlx/service/API.java index c4c09fb2..00704c88 100644 --- a/src/main/java/net/helix/hlx/service/API.java +++ b/src/main/java/net/helix/hlx/service/API.java @@ -915,16 +915,14 @@ private synchronized AbstractResponse findTransactionsStatement(final Map tags = getParameterAsSet(request,"tags",0); for (String tag : tags) { - tag = padTag(tag); tagsTransactions.addAll( TagViewModel.load(tangle, HashFactory.TAG.create(tag)) .getHashes()); } if (tagsTransactions.isEmpty()) { for (String tag : tags) { - tag = padTag(tag); tagsTransactions.addAll( - TagViewModel.load(tangle, HashFactory.TAG.create(tag)) + TagViewModel.loadBundleNonce(tangle, HashFactory.BUNDLENONCE.create(tag)) .getHashes()); } } @@ -974,23 +972,6 @@ private synchronized AbstractResponse findTransactionsStatement(final Maptag is a {@link Hash#NULL_HASH}. - */ - private String padTag(String tag) throws ValidationException { - while (tag.length() < HASH_SIZE) { - tag += '0'; - } - if (tag.equals(Hash.NULL_HASH.toString())) { - throw new ValidationException("Invalid tag input"); - } - return tag; - } - /** * Runs {@link #getParameterAsList(Map, String, int)} and transforms it into a {@link Set}. * diff --git a/src/test/java/net/helix/hlx/controllers/BundleViewModelTest.java b/src/test/java/net/helix/hlx/controllers/BundleViewModelTest.java new file mode 100644 index 00000000..49b81beb --- /dev/null +++ b/src/test/java/net/helix/hlx/controllers/BundleViewModelTest.java @@ -0,0 +1,82 @@ +package net.helix.hlx.controllers; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import net.helix.hlx.conf.MainnetConfig; +import net.helix.hlx.crypto.SpongeFactory; +import net.helix.hlx.model.TransactionHash; +import net.helix.hlx.service.snapshot.SnapshotProvider; +import net.helix.hlx.service.snapshot.impl.SnapshotProviderImpl; +import net.helix.hlx.storage.Tangle; +import net.helix.hlx.storage.rocksDB.RocksDBPersistenceProvider; +import static net.helix.hlx.TransactionTestUtils.getTransactionBytes; + + +public class BundleViewModelTest { + + private static final TemporaryFolder dbFolder = new TemporaryFolder(); + private static final TemporaryFolder logFolder = new TemporaryFolder(); + private static final Tangle tangle = new Tangle(); + private static SnapshotProvider snapshotProvider; + + @Before + public void setup() throws Exception { + dbFolder.create(); + logFolder.create(); + RocksDBPersistenceProvider rocksDBPersistenceProvider; + rocksDBPersistenceProvider = new RocksDBPersistenceProvider( + dbFolder.getRoot().getAbsolutePath(), logFolder.getRoot().getAbsolutePath(), + 1000, Tangle.COLUMN_FAMILIES, Tangle.METADATA_COLUMN_FAMILY); + tangle.addPersistenceProvider(rocksDBPersistenceProvider); + tangle.init(); + snapshotProvider = new SnapshotProviderImpl().init(new MainnetConfig()); + } + + @After + public void shutdown() throws Exception { + tangle.shutdown(); + snapshotProvider.shutdown(); + dbFolder.delete(); + logFolder.delete(); + } + + @Test + public void quietFromHash() throws Exception { + + } + + @Test + public void fromHash() throws Exception { + + } + + @Test + public void getTransactionViewModels() throws Exception { + + } + + @Test + public void quietGetTail() throws Exception { + + } + + @Test + public void getTail() throws Exception { + + } + + @Test + public void firstShouldFindTxTest() throws Exception { + byte[] bytes = getTransactionBytes(); + TransactionViewModel transactionViewModel = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); + transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); + + BundleViewModel result = BundleViewModel.first(tangle); + Assert.assertTrue(result.getHashes().contains(transactionViewModel.getHash())); + } + +} diff --git a/src/test/java/net/helix/hlx/controllers/TipsViewModelTest.java b/src/test/java/net/helix/hlx/controllers/TipsViewModelTest.java new file mode 100644 index 00000000..650f0ae4 --- /dev/null +++ b/src/test/java/net/helix/hlx/controllers/TipsViewModelTest.java @@ -0,0 +1,119 @@ +package net.helix.hlx.controllers; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; + +import net.helix.hlx.model.Hash; +import static net.helix.hlx.TransactionTestUtils.getTransactionHash; + + +public class TipsViewModelTest { + + @Before + public void setup() throws Exception { + + } + + @After + public void shutdown() throws Exception { + + } + + @Test + public void addTipHash() throws Exception { + + } + + @Test + public void removeTipHash() throws Exception { + + } + + @Test + public void setSolid() throws Exception { + + } + + @Test + public void getTips() throws Exception { + + } + + @Test + public void getRandomSolidTipHash() throws Exception { + + } + + @Test + public void getRandomNonSolidTipHash() throws Exception { + + } + + @Test + public void getRandomTipHash() throws Exception { + + } + + @Test + public void nonSolidSize() throws Exception { + + } + + @Test + public void size() throws Exception { + + } + + @Test + public void loadTipHashes() throws Exception { + + } + + @Test + public void nonsolidCapacityLimitedTest() throws ExecutionException, InterruptedException { + TipsViewModel tipsVM = new TipsViewModel(); + int capacity = TipsViewModel.MAX_TIPS; + //fill tips list + for (int i = 0; i < capacity * 2 ; i++) { + Hash hash = getTransactionHash(); + tipsVM.addTipHash(hash); + } + //check that limit wasn't breached + Assert.assertEquals(capacity, tipsVM.nonSolidSize()); + } + + @Test + public void solidCapacityLimitedTest() throws ExecutionException, InterruptedException { + TipsViewModel tipsVM = new TipsViewModel(); + int capacity = TipsViewModel.MAX_TIPS; + //fill tips list + for (int i = 0; i < capacity * 2 ; i++) { + Hash hash = getTransactionHash(); + tipsVM.addTipHash(hash); + tipsVM.setSolid(hash); + } + //check that limit wasn't breached + Assert.assertEquals(capacity, tipsVM.size()); + } + + @Test + public void totalCapacityLimitedTest() throws ExecutionException, InterruptedException { + TipsViewModel tipsVM = new TipsViewModel(); + int capacity = TipsViewModel.MAX_TIPS; + //fill tips list + for (int i = 0; i <= capacity * 4; i++) { + Hash hash = getTransactionHash(); + tipsVM.addTipHash(hash); + if (i % 2 == 1) { + tipsVM.setSolid(hash); + } + } + //check that limit wasn't breached + Assert.assertEquals(capacity * 2, tipsVM.size()); + } + +} diff --git a/src/test/java/net/helix/hlx/controllers/TransactionViewModelTest.java b/src/test/java/net/helix/hlx/controllers/TransactionViewModelTest.java index 5f6fdf67..9066e55d 100644 --- a/src/test/java/net/helix/hlx/controllers/TransactionViewModelTest.java +++ b/src/test/java/net/helix/hlx/controllers/TransactionViewModelTest.java @@ -1,83 +1,89 @@ package net.helix.hlx.controllers; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Random; +import java.util.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.junit.rules.TemporaryFolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.helix.hlx.conf.MainnetConfig; import net.helix.hlx.crypto.SpongeFactory; import net.helix.hlx.model.Hash; -import net.helix.hlx.model.HashFactory; import net.helix.hlx.model.TransactionHash; -import net.helix.hlx.model.persistables.Transaction; import net.helix.hlx.service.snapshot.SnapshotProvider; import net.helix.hlx.service.snapshot.impl.SnapshotProviderImpl; import net.helix.hlx.storage.Tangle; import net.helix.hlx.storage.rocksDB.RocksDBPersistenceProvider; -import org.junit.Assert; -import org.junit.rules.TemporaryFolder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.Random; -import java.util.Set; +import static net.helix.hlx.TransactionTestUtils.getTransactionBytes; +import static net.helix.hlx.TransactionTestUtils.getTransactionHash; +import static net.helix.hlx.TransactionTestUtils.getTransactionBytesWithTrunkAndBranch; -import static org.junit.Assert.*; -/** - * Created by paul on 3/5/17 for iri. - */ public class TransactionViewModelTest { private static final TemporaryFolder dbFolder = new TemporaryFolder(); private static final TemporaryFolder logFolder = new TemporaryFolder(); Logger log = LoggerFactory.getLogger(TransactionViewModelTest.class); - private static Tangle tangle = new Tangle(); + private static final Tangle tangle = new Tangle(); private static SnapshotProvider snapshotProvider; private static final Random seed = new Random(); - public static void setUp() throws Exception { + @Before + public void setup() throws Exception { dbFolder.create(); logFolder.create(); RocksDBPersistenceProvider rocksDBPersistenceProvider; rocksDBPersistenceProvider = new RocksDBPersistenceProvider( - dbFolder.getRoot().getAbsolutePath(), logFolder.getRoot().getAbsolutePath(),1000, - Tangle.COLUMN_FAMILIES, Tangle.METADATA_COLUMN_FAMILY); + dbFolder.getRoot().getAbsolutePath(), logFolder.getRoot().getAbsolutePath(), + 1000, Tangle.COLUMN_FAMILIES, Tangle.METADATA_COLUMN_FAMILY); tangle.addPersistenceProvider(rocksDBPersistenceProvider); tangle.init(); snapshotProvider = new SnapshotProviderImpl().init(new MainnetConfig()); } - public static void tearDown() throws Exception { + @After + public void shutdown() throws Exception { tangle.shutdown(); snapshotProvider.shutdown(); dbFolder.delete(); logFolder.delete(); } + //@Test public void getBundleTransactions() throws Exception { } + //@Test public void getBranchTransaction() throws Exception { } + //@Test public void getTrunkTransaction() throws Exception { } - public void getApprovers() throws Exception { + @Test + public void getApproversTest() throws Exception { TransactionViewModel transactionViewModel, otherTxVM, trunkTx, branchTx; - - byte[] bytes = getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); trunkTx = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); - branchTx = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); - byte[] childTx = getRandomTransactionBytes(); + byte[] childTx = getTransactionBytes(); System.arraycopy(trunkTx.getHash().bytes(), 0, childTx, TransactionViewModel.TRUNK_TRANSACTION_OFFSET, TransactionViewModel.TRUNK_TRANSACTION_SIZE); System.arraycopy(branchTx.getHash().bytes(), 0, childTx, TransactionViewModel.BRANCH_TRANSACTION_OFFSET, TransactionViewModel.BRANCH_TRANSACTION_SIZE); transactionViewModel = new TransactionViewModel(childTx, TransactionHash.calculate(SpongeFactory.Mode.S256, childTx)); - childTx = getRandomTransactionBytes(); + childTx = getTransactionBytes(); System.arraycopy(trunkTx.getHash().bytes(), 0, childTx, TransactionViewModel.TRUNK_TRANSACTION_OFFSET, TransactionViewModel.TRUNK_TRANSACTION_SIZE); System.arraycopy(branchTx.getHash().bytes(), 0, childTx, TransactionViewModel.BRANCH_TRANSACTION_OFFSET, TransactionViewModel.BRANCH_TRANSACTION_SIZE); otherTxVM = new TransactionViewModel(childTx, TransactionHash.calculate(SpongeFactory.Mode.S256, childTx)); @@ -88,212 +94,245 @@ public void getApprovers() throws Exception { branchTx.store(tangle, snapshotProvider.getInitialSnapshot()); Set approvers = trunkTx.getApprovers(tangle).getHashes(); - assertNotEquals(approvers.size(), 0); + Assert.assertNotEquals(approvers.size(), 0); } + //@Test public void fromHash() throws Exception { } + //@Test public void fromHash1() throws Exception { } + //@Test public void update() throws Exception { } - // TODO @fsbbn - public void getBytes() throws Exception { - /* + @Test + public void getBytesTest() throws Exception { for(int i=0; i++ < 1000;) { - int[] trits = getRandomTransactionTrits(seed); - System.arraycopy(new int[TransactionViewModel.VALUE_SIZE], 0, trits, TransactionViewModel.VALUE_OFFSET, TransactionViewModel.VALUE_SIZE); - Converter.copyTrits(seed.nextLong(), trits, TransactionViewModel.VALUE_OFFSET, TransactionViewModel.VALUE_USABLE_SIZE); - TransactionViewModel transactionViewModel = new TransactionViewModel(trits); - transactionViewModel.store(); - assertArrayEquals(transactionViewModel.getBytes(), TransactionViewModel.fromHash(transactionViewModel.getHash()).getBytes()); + byte[] bytes = getTransactionBytes(); + java.nio.ByteBuffer.wrap(bytes, TransactionViewModel.VALUE_OFFSET, TransactionViewModel.VALUE_SIZE).slice().putLong(seed.nextLong()); + Hash hash = getTransactionHash(); + TransactionViewModel transactionViewModel = new TransactionViewModel(bytes, hash); + transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); + Assert.assertArrayEquals(transactionViewModel.getBytes(), TransactionViewModel.fromHash(tangle, transactionViewModel.getHash()).getBytes()); } - */ } + //@Test public void getHash() throws Exception { } + //@Test public void getAddress() throws Exception { } + //@Test public void getTag() throws Exception { } + //@Test public void getBundleHash() throws Exception { } + //@Test public void getTrunkTransactionHash() throws Exception { } + //@Test public void getBranchTransactionHash() throws Exception { } + //@Test public void getValue() throws Exception { } + //@Test public void value() throws Exception { } + //@Test public void setValidity() throws Exception { } + //@Test public void getValidity() throws Exception { } + //@Test public void getCurrentIndex() throws Exception { } + //@Test public void getLastIndex() throws Exception { } + //@Test public void mightExist() throws Exception { } + //@Test public void update1() throws Exception { } + //@Test public void setAnalyzed() throws Exception { } + + //@Test public void dump() throws Exception { } + //@Test public void store() throws Exception { } + //@Test public void updateTips() throws Exception { } + //@Test public void updateReceivedTransactionCount() throws Exception { } + //@Test public void updateApprovers() throws Exception { } + //@Test public void hashesFromQuery() throws Exception { } + //@Test public void approversFromHash() throws Exception { } + //@Test public void fromTag() throws Exception { } + //@Test public void fromBundle() throws Exception { } + //@Test public void fromAddress() throws Exception { } + //@Test public void getTransactionAnalyzedFlag() throws Exception { } + //@Test public void getType() throws Exception { } + //@Test public void setArrivalTime() throws Exception { } + //@Test public void getArrivalTime() throws Exception { } - public void updateHeightShouldWork() throws Exception { + @Test + public void updateHeightShouldWorkTest() throws Exception { int count = 4; TransactionViewModel[] transactionViewModels = new TransactionViewModel[count]; - Hash hash = getRandomTransactionHash(); - transactionViewModels[0] = new TransactionViewModel(getRandomTransactionWithTrunkAndBranch(Hash.NULL_HASH, - Hash.NULL_HASH), hash); + Hash hash = getTransactionHash(); + transactionViewModels[0] = new TransactionViewModel(getTransactionBytesWithTrunkAndBranch(Hash.NULL_HASH, Hash.NULL_HASH), hash); transactionViewModels[0].store(tangle, snapshotProvider.getInitialSnapshot()); for(int i = 0; ++i < count; ) { - transactionViewModels[i] = new TransactionViewModel(getRandomTransactionWithTrunkAndBranch(hash, - Hash.NULL_HASH), hash = getRandomTransactionHash()); + transactionViewModels[i] = new TransactionViewModel(getTransactionBytesWithTrunkAndBranch(hash, Hash.NULL_HASH), hash = getTransactionHash()); transactionViewModels[i].store(tangle, snapshotProvider.getInitialSnapshot()); } transactionViewModels[count-1].updateHeights(tangle, snapshotProvider.getInitialSnapshot()); for(int i = count; i > 1; ) { - assertEquals(i, TransactionViewModel.fromHash(tangle, transactionViewModels[--i].getHash()).getHeight()); + Assert.assertEquals(i, TransactionViewModel.fromHash(tangle, transactionViewModels[--i].getHash()).getHeight()); } } - public void updateHeightPrefilledSlotShouldFail() throws Exception { + @Test + public void updateHeightPrefilledSlotShouldFailTest() throws Exception { int count = 4; TransactionViewModel[] transactionViewModels = new TransactionViewModel[count]; - Hash hash = getRandomTransactionHash(); + Hash hash = getTransactionHash(); for(int i = 0; ++i < count; ) { - transactionViewModels[i] = new TransactionViewModel(getRandomTransactionWithTrunkAndBranch(hash, - Hash.NULL_HASH), hash = getRandomTransactionHash()); + transactionViewModels[i] = new TransactionViewModel(getTransactionBytesWithTrunkAndBranch(hash, Hash.NULL_HASH), hash = getTransactionHash()); transactionViewModels[i].store(tangle, snapshotProvider.getInitialSnapshot()); } transactionViewModels[count-1].updateHeights(tangle, snapshotProvider.getInitialSnapshot()); for(int i = count; i > 1; ) { - assertEquals(0, TransactionViewModel.fromHash(tangle, transactionViewModels[--i].getHash()).getHeight()); + Assert.assertEquals(0, TransactionViewModel.fromHash(tangle, transactionViewModels[--i].getHash()).getHeight()); } } - public void findShouldBeSuccessful() throws Exception { - byte[] bytes = getRandomTransactionBytes(); + @Test + public void findShouldBeSuccessfulTest() throws Exception { + byte[] bytes = getTransactionBytes(); TransactionViewModel transactionViewModel = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); Hash hash = transactionViewModel.getHash(); - TransactionViewModel tvm = TransactionViewModel.find(tangle, Arrays.copyOf(hash.bytes(), MainnetConfig.Defaults.REQ_HASH_SIZE)); - Assert.assertArrayEquals(tvm.getBytes(), transactionViewModel.getBytes()); + Assert.assertArrayEquals(TransactionViewModel.find(tangle, + Arrays.copyOf(hash.bytes(), MainnetConfig.Defaults.REQ_HASH_SIZE)).getBytes(), transactionViewModel.getBytes()); } - public void findShouldReturnNull() throws Exception { - byte[] bytes = getRandomTransactionBytes(); + @Test + public void findShouldReturnNullTest() throws Exception { + byte[] bytes = getTransactionBytes(); TransactionViewModel transactionViewModel = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); - bytes = getRandomTransactionBytes(); + bytes = getTransactionBytes(); TransactionViewModel transactionViewModelNoSave = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); Hash hash = transactionViewModelNoSave.getHash(); - Assert.assertFalse(Arrays.equals(TransactionViewModel.find(tangle, Arrays.copyOf(hash.bytes(), MainnetConfig.Defaults.REQ_HASH_SIZE)).getBytes(), transactionViewModel.getBytes())); + Assert.assertFalse(Arrays.equals(TransactionViewModel.find(tangle, + Arrays.copyOf(hash.bytes(), new MainnetConfig().getRequestHashSize())).getBytes(), transactionViewModel.getBytes())); } - - public void testManyTXInDB() throws Exception { + //@Test + public void testManyTXInDBTest() throws Exception { int i, j; LinkedList hashes = new LinkedList<>(); Hash hash; - hash = getRandomTransactionHash(); + hash = getTransactionHash(); hashes.add(hash); long start, diff, diffget; long subSumDiff=0,maxdiff=0, sumdiff = 0; @@ -301,13 +340,13 @@ public void testManyTXInDB() throws Exception { int interval1 = 50; int interval = interval1*10; log.info("Starting Test. #TX: {}", TransactionViewModel.getNumberOfStoredTransactions(tangle)); - new TransactionViewModel(getRandomTransactionWithTrunkAndBranch(Hash.NULL_HASH, Hash.NULL_HASH), hash).store(tangle, snapshotProvider.getInitialSnapshot()); + new TransactionViewModel(getTransactionBytesWithTrunkAndBranch(Hash.NULL_HASH, Hash.NULL_HASH), hash).store(tangle, snapshotProvider.getInitialSnapshot()); TransactionViewModel transactionViewModel; boolean pop = false; for (i = 0; i++ < max;) { - hash = getRandomTransactionHash(); + hash = getTransactionHash(); j = hashes.size(); - transactionViewModel = new TransactionViewModel(getRandomTransactionWithTrunkAndBranch(hashes.get(seed.nextInt(j)), hashes.get(seed.nextInt(j))), hash); + transactionViewModel = new TransactionViewModel(getTransactionBytesWithTrunkAndBranch(hashes.get(seed.nextInt(j)), hashes.get(seed.nextInt(j))), hash); start = System.nanoTime(); transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); diff = System.nanoTime() - start; @@ -324,7 +363,10 @@ public void testManyTXInDB() throws Exception { hashes.removeFirst(); } + //log.info("{}", new String(new char[(int) ((diff/ 10000))]).replace('\0', '|')); if(i % interval1 == 0) { + //log.info("{}", new String(new char[(int) (diff / 50000)]).replace('\0', '-')); + //log.info("{}", new String(new char[(int) ((subSumDiff / interval1 / 100000))]).replace('\0', '|')); sumdiff += subSumDiff; subSumDiff = 0; } @@ -338,32 +380,14 @@ public void testManyTXInDB() throws Exception { log.info("Done. #TX: {}", TransactionViewModel.getNumberOfStoredTransactions(tangle)); } - private Transaction getRandomTransaction(Random seed) { - Transaction transaction = new Transaction(); - byte[] bytes = new byte[TransactionViewModel.SIGNATURE_MESSAGE_FRAGMENT_SIZE]; - seed.nextBytes(bytes); - transaction.bytes = bytes; - return transaction; - } - public static byte[] getRandomTransactionWithTrunkAndBranch(Hash trunk, Hash branch) { - byte[] bytes = getRandomTransactionBytes(); - System.arraycopy(trunk.bytes(), 0, bytes, TransactionViewModel.TRUNK_TRANSACTION_OFFSET, - TransactionViewModel.TRUNK_TRANSACTION_SIZE); - System.arraycopy(branch.bytes(), 0, bytes, TransactionViewModel.BRANCH_TRANSACTION_OFFSET, - TransactionViewModel.BRANCH_TRANSACTION_SIZE); - return bytes; - } + @Test + public void firstShouldFindTxTest() throws Exception { + byte[] bytes = getTransactionBytes(); + TransactionViewModel transactionViewModel = new TransactionViewModel(bytes, TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); + transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); - public static byte[] getRandomTransactionBytes() { - byte[] bytes = new byte[TransactionViewModel.SIZE]; - // TODO generate array of random ints in 0x10 range. - // seed.nextInt(0x10)+0x10 - seed.nextBytes(bytes); - return bytes; - } - public static Hash getRandomTransactionHash() { - byte[] bytes = new byte[Hash.SIZE_IN_BYTES]; - seed.nextBytes(bytes); - return HashFactory.TRANSACTION.create(bytes); + TransactionViewModel result = TransactionViewModel.first(tangle); + Assert.assertEquals(transactionViewModel.getHash(), result.getHash()); } + } diff --git a/src/test/java/net/helix/hlx/model/HashTest.java b/src/test/java/net/helix/hlx/model/HashTest.java index 7b693497..61edd41d 100644 --- a/src/test/java/net/helix/hlx/model/HashTest.java +++ b/src/test/java/net/helix/hlx/model/HashTest.java @@ -1,33 +1,34 @@ package net.helix.hlx.model; -import net.helix.hlx.controllers.TransactionViewModel; -import net.helix.hlx.controllers.TransactionViewModelTest; -import net.helix.hlx.crypto.SpongeFactory; +import java.util.Arrays; + import org.bouncycastle.util.encoders.Hex; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; +import net.helix.hlx.controllers.TransactionViewModel; +import net.helix.hlx.crypto.SpongeFactory; +import static net.helix.hlx.TransactionTestUtils.getTransactionBytes; public class HashTest { @Test public void calculateTest() throws Exception { - Hash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, TransactionViewModelTest.getRandomTransactionBytes()); + Hash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, getTransactionBytes()); Assert.assertNotEquals(0, hash.hashCode()); Assert.assertNotEquals(null, hash.bytes()); } @Test public void calculateTest1() throws Exception { - Hash hash = TransactionHash.calculate(TransactionViewModelTest.getRandomTransactionBytes(), 0, 128, SpongeFactory.create(SpongeFactory.Mode.S256)); + Hash hash = TransactionHash.calculate(getTransactionBytes(), 0, 128, SpongeFactory.create(SpongeFactory.Mode.S256)); Assert.assertNotEquals(null, hash.bytes()); Assert.assertNotEquals(0, hash.hashCode()); } @Test public void calculateTest2() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(bytes, 0, TransactionViewModel.ADDRESS_SIZE, SpongeFactory.create(SpongeFactory.Mode.S256)); Assert.assertNotEquals(0, hash.hashCode()); Assert.assertNotEquals(null, hash.bytes()); @@ -52,23 +53,23 @@ public void leadingZerosTest() throws Exception { @Test public void bytesTest() throws Exception { - TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, TransactionViewModelTest.getRandomTransactionBytes()); + TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, getTransactionBytes()); Assert.assertFalse(Arrays.equals(new byte[Hash.SIZE_IN_BYTES], hash.bytes())); } @Test public void equalsTest() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); TransactionHash hash1 = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); Assert.assertTrue(hash.equals(hash1)); Assert.assertFalse(hash.equals(Hash.NULL_HASH)); - Assert.assertFalse(hash.equals(TransactionHash.calculate(SpongeFactory.Mode.S256, TransactionViewModelTest.getRandomTransactionBytes()))); + Assert.assertFalse(hash.equals(TransactionHash.calculate(SpongeFactory.Mode.S256, getTransactionBytes()))); } @Test public void hashCodeTest() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); Assert.assertNotEquals(hash.hashCode(), 0); // TODO Find actual value for this assert @@ -77,7 +78,7 @@ public void hashCodeTest() throws Exception { @Test public void toHexStringTest() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); Assert.assertEquals(Hex.toHexString(Hash.NULL_HASH.bytes()), "0000000000000000000000000000000000000000000000000000000000000000"); Assert.assertNotEquals(Hex.toHexString(hash.bytes()), "0000000000000000000000000000000000000000000000000000000000000000"); @@ -86,7 +87,7 @@ public void toHexStringTest() throws Exception { @Test public void toStringTest() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); Hash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); Assert.assertEquals(Hash.NULL_HASH.toString(), "0000000000000000000000000000000000000000000000000000000000000000"); Assert.assertNotEquals(hash.toString(), "0000000000000000000000000000000000000000000000000000000000000000"); @@ -95,7 +96,7 @@ public void toStringTest() throws Exception { @Test public void txBytesTest() throws Exception { - byte[] bytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] bytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, bytes); Assert.assertTrue(Arrays.equals(new byte[Hash.SIZE_IN_BYTES], Hash.NULL_HASH.bytes())); Assert.assertFalse(Arrays.equals(new byte[Hash.SIZE_IN_BYTES], hash.bytes())); @@ -104,7 +105,7 @@ public void txBytesTest() throws Exception { @Test public void compareToTest() throws Exception { - byte[] randomTransactionBytes = TransactionViewModelTest.getRandomTransactionBytes(); + byte[] randomTransactionBytes = getTransactionBytes(); TransactionHash hash = TransactionHash.calculate(SpongeFactory.Mode.S256, randomTransactionBytes); Assert.assertEquals(hash.compareTo(Hash.NULL_HASH), -Hash.NULL_HASH.compareTo(hash)); } diff --git a/src/test/java/net/helix/hlx/model/persistables/TransactionTest.java b/src/test/java/net/helix/hlx/model/persistables/TransactionTest.java new file mode 100644 index 00000000..c4b660a2 --- /dev/null +++ b/src/test/java/net/helix/hlx/model/persistables/TransactionTest.java @@ -0,0 +1,47 @@ +package net.helix.hlx.model.persistables; + +import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import net.helix.hlx.TransactionTestUtils; +import net.helix.hlx.controllers.TransactionViewModel; +import net.helix.hlx.model.Hash; + + +public class TransactionTest { + + @Test + public void bytesTest() { + Transaction t = TransactionTestUtils.getTransaction(); + + Transaction newtx = new Transaction(); + newtx.read(t.bytes()); + newtx.readMetadata(t.metadata()); + + assertArrayEquals("metadata should be the same in the copy", t.metadata(), newtx.metadata()); + assertArrayEquals("bytes should be the same in the copy", t.bytes(), newtx.bytes()); + } + + @Test + public void fromBytesTest() { + byte[] bytes = TransactionTestUtils.getTransactionBytes(); + + TransactionViewModel tvm = new TransactionViewModel(bytes, Hash.NULL_HASH); + tvm.getAddressHash(); + tvm.getTrunkTransactionHash(); + tvm.getBranchTransactionHash(); + tvm.getBundleHash(); + tvm.getTagValue(); + tvm.getBundleNonceHash(); //tvm.getObsoleteTagValue(); + tvm.setAttachmentData(); + tvm.setMetadata(); + + assertArrayEquals("bytes in the TVM should be unmodified", tvm.getBytes(), bytes); + + Transaction tvmTransaction = tvm.getTransaction(); + + assertEquals("branch in transaction should be the same as in the tvm", tvmTransaction.branch, tvm.getTransaction().branch); + } + +} diff --git a/src/test/java/net/helix/hlx/service/APIIntegrationTest.java b/src/test/java/net/helix/hlx/service/APIIntegrationTest.java index 24467ef2..18345b47 100644 --- a/src/test/java/net/helix/hlx/service/APIIntegrationTest.java +++ b/src/test/java/net/helix/hlx/service/APIIntegrationTest.java @@ -64,7 +64,7 @@ public class APIIntegrationTest { private static final String[] URIS = {"udp://8.8.8.8:14266", "udp://8.8.8.5:14266"}; private static final String[] ADDRESSES = {"d0e7e549a4ffe5b4f8343973f0237db9ede3597baced22715c22dcd8c76ae738"}; private static final String[] HASHES = {"0000f13be306d278fae139dc4a54deb40389a8d1c3677a872a9a198f57aad343"}; - private static final String[] TX_HEX = {"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2eb2d5297f4e70f3e40e3d7aa3f5c1d7405264aeb72232d06776605d8b6121100000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d092fc0000000000000000000000000000000005031b48d241283c312c68c777bc4563ddd7cbe1ae6a2c58079e1bf3cfef826790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068656c6c6f68656c0000016b6c93ca0e0000000000000000000000000000007f000000000000006f0000000000000000000000000000007f00000000000091b0"}; + private static final String[] TX_HEX = {"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2eb2d5297f4e70f3e40e3d7aa3f5c1d7405264aeb72232d06776605d8b6121100000000000000005551b48d241283c312c68c555bc4563ddd7cbe1ae6a2c58079e1bf3cfef82000000000005d092fc0000000000000000000000000000000005031b48d241283c312c68c777bc4563ddd7cbe1ae6a2c58079e1bf3cfef826790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068656c6c6f68656c0000016b6c93ca0e0000000000000000000000000000007f000000000000015d000000000000000000000000000000000000000000000000"}; private static final String NULL_HASH = "0000000000000000000000000000000000000000000000000000000000000000"; private static final String[] NULL_HASH_LIST = {NULL_HASH}; private static final TemporaryFolder dbFolder = new TemporaryFolder(); @@ -505,9 +505,7 @@ public void shouldSendTransactionAndFetchByAddressTest() { Assert.assertThat(hashes, hasItem(hash)); } - //@Test - //TODO: - //HAS TO BE FIXED: transactions can't be found by tag + @Test public void shouldSendTransactionAndFetchByTagTest() { List tx = sendTransfer(TX_HEX); String temp = (String) tx.get(0); @@ -519,10 +517,10 @@ public void shouldSendTransactionAndFetchByTagTest() { List hashes = findTransactions("tags", tags); Assert.assertThat(hashes, hasItem(hash)); - //ObsoleteTag - String[] obsoleteTags = {temp.substring(TransactionViewModel.BUNDLE_NONCE_OFFSET * 2, + //BundleNonce (ObsoleteTag) + String[] bundleNonces = {temp.substring(TransactionViewModel.BUNDLE_NONCE_OFFSET * 2, (TransactionViewModel.BUNDLE_NONCE_OFFSET + TransactionViewModel.BUNDLE_NONCE_SIZE) * 2)}; - List hashes1 = findTransactions("tags", obsoleteTags); + List hashes1 = findTransactions("tags", bundleNonces); Assert.assertThat(hashes1, hasItem(hash)); } diff --git a/src/test/java/net/helix/hlx/storage/TangleTest.java b/src/test/java/net/helix/hlx/storage/TangleTest.java index 796265ec..8cc0cc5e 100644 --- a/src/test/java/net/helix/hlx/storage/TangleTest.java +++ b/src/test/java/net/helix/hlx/storage/TangleTest.java @@ -65,7 +65,7 @@ public void getKeysStartingWithValueTest() throws Exception { TransactionHash.calculate(SpongeFactory.Mode.S256, bytes)); transactionViewModel.store(tangle, snapshotProvider.getInitialSnapshot()); Set tag = tangle.keysStartingWith(Tag.class, - Arrays.copyOf(transactionViewModel.getTagValue().bytes(), 15)); + Arrays.copyOf(transactionViewModel.getTagValue().bytes(), TransactionViewModel.TAG_SIZE - 2)); Assert.assertNotEquals(tag.size(), 0); }