Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Commit

Permalink
Fixes DB over-storing transactions due to concurrency
Browse files Browse the repository at this point in the history
Upgrade to RocksDB 5.7.3
Upgrades findTransaction logic to match spec (Multi-field intersection, Input field limits)
Unified API input validation
  • Loading branch information
alon-e committed Nov 8, 2017
1 parent 40f27ae commit 567a39a
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 315 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RUN mvn clean package

FROM openjdk:jre-slim
WORKDIR /iri
COPY --from=builder /iri/target/iri-1.4.1.1.jar iri.jar
COPY --from=builder /iri/target/iri-1.4.1.2.jar iri.jar
COPY logback.xml /iri
VOLUME /iri

Expand Down
6 changes: 6 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
1.4.1.2
- Fixes DB over-storing transactions due to concurrency
- Upgrade to RocksDB 5.7.3
- Upgrades findTransaction logic to match spec (Multi-field intersection, Input field limits)
- Unified API input validation

1.4.1.1
- Fixes CORS issue introduced with last release
- attachToTangle no longer overwrites tag field unconditionally
Expand Down
6 changes: 3 additions & 3 deletions dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.iota</groupId>
<artifactId>iri</artifactId>
<name>IRI</name>
<version>1.4.1</version>
<version>1.4.1.2</version>
<description>IOTA Reference Implementation</description>
<scm>
<connection>scm:git:git://github.com/iotaledger/iri.git</connection>
Expand Down Expand Up @@ -61,7 +61,7 @@
<executions>
<execution>
<id>enforce</id>
<phase>verify</phase>
<phase>package</phase>
<goals>
<goal>enforce</goal>
</goals>
Expand All @@ -74,7 +74,7 @@
<urn>org.slf4j:slf4j-api:1.7.25:jar:null:compile:da76ca59f6a57ee3102f8f9bd9cee742973efa8a</urn>
<urn>ch.qos.logback:logback-classic:1.2.3:jar:null:compile:7c4f3c474fb2c041d8028740440937705ebb473a</urn>
<urn>commons-io:commons-io:2.5:jar:null:compile:2852e6e05fbb95076fc091f6d1780f1f8fe35e0f</urn>
<urn>org.rocksdb:rocksdbjni:5.1.4:jar:null:compile:1924f10f010ddf724a41d2ce6903a706bda7f1b6</urn>
<urn>org.rocksdb:rocksdbjni:5.7.3:jar:null:compile:421b44ad957a2b6cce5adedc204db551831b553d</urn>
<urn>com.google.code.gson:gson:2.8.1:jar:null:compile:02a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0</urn>
<urn>io.undertow:undertow-core:${undertow.version}:jar:null:compile:e5764e5017bfe8c2dd421dc80035e5165501bfda</urn>
<urn>io.undertow:undertow-servlet:${undertow.version}:jar:null:compile:0e2850a558e70a2d72d9a3e782c7b6fde2d9f1c7</urn>
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.iota</groupId>
<artifactId>iri</artifactId>
<version>1.4.1.1</version>
<version>1.4.1.2</version>

<name>IRI</name>
<description>IOTA Reference Implementation</description>
Expand Down Expand Up @@ -76,7 +76,7 @@
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>5.1.4</version>
<version>5.7.3</version>
</dependency>

<!-- json support -->
Expand Down Expand Up @@ -212,7 +212,7 @@
<executions>
<execution>
<id>enforce</id>
<phase>verify</phase>
<phase>package</phase>
<goals>
<goal>enforce</goal>
</goals>
Expand All @@ -232,7 +232,7 @@
<urn>org.slf4j:slf4j-api:1.7.25:jar:null:compile:da76ca59f6a57ee3102f8f9bd9cee742973efa8a</urn>
<urn>ch.qos.logback:logback-classic:1.2.3:jar:null:compile:7c4f3c474fb2c041d8028740440937705ebb473a</urn>
<urn>commons-io:commons-io:2.5:jar:null:compile:2852e6e05fbb95076fc091f6d1780f1f8fe35e0f</urn>
<urn>org.rocksdb:rocksdbjni:5.1.4:jar:null:compile:1924f10f010ddf724a41d2ce6903a706bda7f1b6</urn>
<urn>org.rocksdb:rocksdbjni:5.7.3:jar:null:compile:421b44ad957a2b6cce5adedc204db551831b553d</urn>
<urn>com.google.code.gson:gson:2.8.1:jar:null:compile:02a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0</urn>
<urn>io.undertow:undertow-core:${undertow.version}:jar:null:compile:e5764e5017bfe8c2dd421dc80035e5165501bfda</urn>
<urn>io.undertow:undertow-servlet:${undertow.version}:jar:null:compile:0e2850a558e70a2d72d9a3e782c7b6fde2d9f1c7</urn>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/iota/iri/IRI.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class IRI {

public static final String MAINNET_NAME = "IRI";
public static final String TESTNET_NAME = "IRI Testnet";
public static final String VERSION = "1.4.1.1";
public static final String VERSION = "1.4.1.2";
public static Iota iota;
public static API api;
public static IXI ixi;
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/iota/iri/conf/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ public enum DefaultConfSettings {
MIN_RANDOM_WALKS,
MAX_RANDOM_WALKS,
MAX_FIND_TRANSACTIONS,
MAX_REQUESTS_LIST,
MAX_GET_TRYTES,
MAX_BODY_LENGTH,
MAX_DEPTH,
MAINNET_MWM,
TESTNET_MWM,
Expand Down Expand Up @@ -104,7 +106,9 @@ public enum DefaultConfSettings {
conf.put(DefaultConfSettings.MAX_DEPTH.name(), "15");

conf.put(DefaultConfSettings.MAX_FIND_TRANSACTIONS.name(), "100000");
conf.put(DefaultConfSettings.MAX_REQUESTS_LIST.name(), "1000");
conf.put(DefaultConfSettings.MAX_GET_TRYTES.name(), "10000");
conf.put(DefaultConfSettings.MAX_BODY_LENGTH.name(), "1000000");
conf.put(DefaultConfSettings.ZMQ_ENABLED.name(), "false");
conf.put(DefaultConfSettings.ZMQ_PORT.name(), "5556");
conf.put(DefaultConfSettings.ZMQ_IPC.name(), "ipc://iri");
Expand Down
70 changes: 39 additions & 31 deletions src/main/java/com/iota/iri/controllers/TransactionViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,22 @@ public class TransactionViewModel {
private int[] trits;
public int weightMagnitude;

public static TransactionViewModel find(final Tangle tangle, byte[] hash) throws Exception {
TransactionViewModel transactionViewModel = new TransactionViewModel((Transaction) tangle.find(Transaction.class, hash), new Hash(hash));
if(!transactionViewModel.getHash().equals(Hash.NULL_HASH) && !transactionViewModel.transaction.parsed) {
public static void fillMetadata(final Tangle tangle, TransactionViewModel transactionViewModel) throws Exception {
if (transactionViewModel.getHash().equals(Hash.NULL_HASH)) { return; }
if(transactionViewModel.getType() == FILLED_SLOT && !transactionViewModel.transaction.parsed) {
tangle.saveBatch(transactionViewModel.getMetadataSaveBatch());
}
}

public static TransactionViewModel find(final Tangle tangle, byte[] hash) throws Exception {
TransactionViewModel transactionViewModel = new TransactionViewModel((Transaction) tangle.find(Transaction.class, hash), new Hash(hash));
fillMetadata(tangle, transactionViewModel);
return transactionViewModel;
}

public static TransactionViewModel fromHash(final Tangle tangle, final Hash hash) throws Exception {
TransactionViewModel transactionViewModel = new TransactionViewModel((Transaction) tangle.load(Transaction.class, hash), hash);
if(!transactionViewModel.getHash().equals(Hash.NULL_HASH) && !transactionViewModel.transaction.parsed) {
tangle.saveBatch(transactionViewModel.getMetadataSaveBatch());
}
fillMetadata(tangle, transactionViewModel);
return transactionViewModel;
}

Expand Down Expand Up @@ -118,7 +121,7 @@ public boolean update(final Tangle tangle, String item) throws Exception {
if(hash.equals(Hash.NULL_HASH)) {
return false;
}
return tangle.update(transaction, getHash(), item);
return tangle.update(transaction, hash, item);
}

public TransactionViewModel getBranchTransaction(final Tangle tangle) throws Exception {
Expand Down Expand Up @@ -149,16 +152,16 @@ public synchronized int[] trits() {
}

public void delete(Tangle tangle) throws Exception {
tangle.delete(Transaction.class, getHash());
tangle.delete(Transaction.class, hash);
}

public List<Pair<Indexable, Persistable>> getMetadataSaveBatch() throws Exception {
List<Pair<Indexable, Persistable>> hashesList = new ArrayList<>();
hashesList.add(new Pair<>(getAddressHash(), new Address(getHash())));
hashesList.add(new Pair<>(getBundleHash(), new Bundle(getHash())));
hashesList.add(new Pair<>(getBranchTransactionHash(), new Approvee(getHash())));
hashesList.add(new Pair<>(getTrunkTransactionHash(), new Approvee(getHash())));
hashesList.add(new Pair<>(getObsoleteTagValue(), new Tag(getHash())));
hashesList.add(new Pair<>(getAddressHash(), new Address(hash)));
hashesList.add(new Pair<>(getBundleHash(), new Bundle(hash)));
hashesList.add(new Pair<>(getBranchTransactionHash(), new Approvee(hash)));
hashesList.add(new Pair<>(getTrunkTransactionHash(), new Approvee(hash)));
hashesList.add(new Pair<>(getObsoleteTagValue(), new Tag(hash)));
setAttachmentData();
setMetadata();
return hashesList;
Expand All @@ -168,7 +171,7 @@ public List<Pair<Indexable, Persistable>> getSaveBatch() throws Exception {
List<Pair<Indexable, Persistable>> hashesList = new ArrayList<>();
hashesList.addAll(getMetadataSaveBatch());
getBytes();
hashesList.add(new Pair<>(getHash(), transaction));
hashesList.add(new Pair<>(hash, transaction));
return hashesList;
}

Expand All @@ -182,18 +185,23 @@ public static TransactionViewModel first(Tangle tangle) throws Exception {
}

public TransactionViewModel next(Tangle tangle) throws Exception {
Pair<Indexable, Persistable> transactionPair = tangle.next(Transaction.class, getHash());
Pair<Indexable, Persistable> transactionPair = tangle.next(Transaction.class, hash);
if(transactionPair != null && transactionPair.hi != null) {
return new TransactionViewModel((Transaction) transactionPair.hi, (Hash) transactionPair.low);
}
return null;
}

public boolean store(Tangle tangle) throws Exception {
if(!exists(tangle, getHash()) && !getHash().equals(Hash.NULL_HASH)) {
return tangle.saveBatch(getSaveBatch());
if (hash.equals(Hash.NULL_HASH) || exists(tangle, hash)) {
return false;
}
return false;

List<Pair<Indexable, Persistable>> batch = getSaveBatch();
if (exists(tangle, hash)) {
return false;
}
return tangle.saveBatch(batch);
}

public ApproveeViewModel getApprovers(Tangle tangle) throws Exception {
Expand Down Expand Up @@ -388,26 +396,26 @@ private void updateHeight(long height) throws Exception {
}

public void updateHeights(final Tangle tangle) throws Exception {
TransactionViewModel transaction = this, trunk = this.getTrunkTransaction(tangle);
TransactionViewModel transactionVM = this, trunk = this.getTrunkTransaction(tangle);
Stack<Hash> transactionViewModels = new Stack<>();
transactionViewModels.push(transaction.getHash());
transactionViewModels.push(transactionVM.getHash());
while(trunk.getHeight() == 0 && trunk.getType() != PREFILLED_SLOT && !trunk.getHash().equals(Hash.NULL_HASH)) {
transaction = trunk;
trunk = transaction.getTrunkTransaction(tangle);
transactionViewModels.push(transaction.getHash());
transactionVM = trunk;
trunk = transactionVM.getTrunkTransaction(tangle);
transactionViewModels.push(transactionVM.getHash());
}
while(transactionViewModels.size() != 0) {
transaction = TransactionViewModel.fromHash(tangle, transactionViewModels.pop());
if(trunk.getHash().equals(Hash.NULL_HASH) && trunk.getHeight() == 0 && !transaction.getHash().equals(Hash.NULL_HASH)) {
transaction.updateHeight(1L);
transaction.update(tangle, "height");
} else if ( trunk.getType() != PREFILLED_SLOT && transaction.getHeight() == 0){
transaction.updateHeight(1 + trunk.getHeight());
transaction.update(tangle, "height");
transactionVM = TransactionViewModel.fromHash(tangle, transactionViewModels.pop());
if(trunk.getHash().equals(Hash.NULL_HASH) && trunk.getHeight() == 0 && !transactionVM.getHash().equals(Hash.NULL_HASH)) {
transactionVM.updateHeight(1L);
transactionVM.update(tangle, "height");
} else if ( trunk.getType() != PREFILLED_SLOT && transactionVM.getHeight() == 0){
transactionVM.updateHeight(1 + trunk.getHeight());
transactionVM.update(tangle, "height");
} else {
break;
}
trunk = transaction;
trunk = transactionVM;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/iota/iri/model/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class Transaction implements Persistable {
public long attachmentTimestampUpperBound;

public int validity = 0;
public int type = 1;
public int type = TransactionViewModel.PREFILLED_SLOT;
public long arrivalTime = 0;

//public boolean confirmed = false;
Expand All @@ -48,6 +48,7 @@ public void read(byte[] bytes) {
if(bytes != null) {
this.bytes = new byte[SIZE];
System.arraycopy(bytes, 0, this.bytes, 0, SIZE);
this.type = TransactionViewModel.FILLED_SLOT;
}
}

Expand Down
Loading

0 comments on commit 567a39a

Please sign in to comment.