-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transaction queue #247
base: dev
Are you sure you want to change the base?
Transaction queue #247
Changes from 13 commits
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
00d07ab
7613ee9
403ac1b
98fb517
716838b
20ef88a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.limechain.network.protocol.transaction.scale; | ||
|
||
import com.limechain.network.protocol.warp.dto.Extrinsics; | ||
import io.emeraldpay.polkaj.scale.ScaleCodecReader; | ||
import io.emeraldpay.polkaj.scale.ScaleReader; | ||
|
||
public class TransactionsReader implements ScaleReader<Extrinsics[]> { | ||
|
||
@Override | ||
public Extrinsics[] read(ScaleCodecReader reader) { | ||
int size = reader.readCompactInt(); | ||
Extrinsics[] transactions = new Extrinsics[size]; | ||
for (int i = 0; i < size; i++) { | ||
transactions[i] = new Extrinsics(reader.readByteArray()); | ||
} | ||
return transactions; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.limechain.network.protocol.transaction.scale; | ||
|
||
import com.limechain.network.protocol.warp.dto.Extrinsics; | ||
import io.emeraldpay.polkaj.scale.ScaleCodecWriter; | ||
import io.emeraldpay.polkaj.scale.ScaleWriter; | ||
|
||
import java.io.IOException; | ||
|
||
public class TransactionsWriter implements ScaleWriter<Extrinsics[]> { | ||
|
||
@Override | ||
public void write(ScaleCodecWriter writer, Extrinsics[] transactions) throws IOException { | ||
writer.writeCompact(transactions.length); | ||
for (int i = 0; i < transactions.length; i++) { | ||
writer.writeAsList(transactions[i].getExtrinsic()); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.limechain.network.protocol.transaction.state; | ||
|
||
import com.limechain.utils.HashUtils; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
@NoArgsConstructor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No arg constructor is implied if no other constructor is found. |
||
public class Pool { | ||
final Map<byte[], ValidTransaction> transactions = new HashMap<>(); | ||
|
||
public ValidTransaction get(byte[] extrinisics) { | ||
byte[] key = HashUtils.hashWithBlake2b(extrinisics); | ||
|
||
return transactions.get(key); | ||
} | ||
|
||
public ValidTransaction[] transactions() { | ||
return transactions.values().toArray(ValidTransaction[]::new); | ||
} | ||
|
||
public byte[] insert(ValidTransaction validTransaction){ | ||
byte[] key = HashUtils.hashWithBlake2b(validTransaction.getExtrinsic()); | ||
transactions.put(key, validTransaction); | ||
return key; | ||
} | ||
|
||
public void removeExtrinsic(byte[] extrinsic){ | ||
byte[] key = HashUtils.hashWithBlake2b(extrinsic); | ||
transactions.remove(key); | ||
} | ||
|
||
public int length(){ | ||
return transactions.size(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package com.limechain.network.protocol.transaction.state; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.extern.java.Log; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.PriorityQueue; | ||
import java.util.Queue; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.Future; | ||
import java.util.concurrent.TimeoutException; | ||
|
||
@Log | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class TransactionState { | ||
private static final TransactionState INSTANCE = new TransactionState(); | ||
private final Pool transactionPool = new Pool(); | ||
private final ExecutorService executor = Executors.newSingleThreadExecutor(); | ||
@Getter | ||
@Setter | ||
private Queue<ValidTransaction> transactionQueue = new PriorityQueue<>(); | ||
|
||
public static TransactionState getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
public void pushTransaction(ValidTransaction validTransaction) { | ||
transactionQueue.add(validTransaction); | ||
} | ||
|
||
public ValidTransaction popTransaction() { | ||
return transactionQueue.poll(); | ||
} | ||
|
||
public ValidTransaction popTransactionWithTimer(long timeout) throws InterruptedException { | ||
ValidTransaction validTransaction = popTransaction(); | ||
if (validTransaction != null) return validTransaction; | ||
|
||
Future<ValidTransaction> futureTransaction = popFutureTransaction(); | ||
|
||
try { | ||
return futureTransaction.get(timeout, java.util.concurrent.TimeUnit.MILLISECONDS); | ||
} catch (ExecutionException e) { | ||
log.severe("Error while waiting for transaction: " + e.getMessage()); | ||
} catch (TimeoutException e) { | ||
futureTransaction.cancel(true); | ||
} catch (InterruptedException e) { | ||
if (Thread.interrupted()) | ||
throw new InterruptedException(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@NotNull | ||
private Future<ValidTransaction> popFutureTransaction() { | ||
return executor.submit(() -> { | ||
ValidTransaction transaction = null; | ||
while (transaction == null) { | ||
transaction = popTransaction(); | ||
Thread.sleep(50); | ||
bokoto000 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
return transaction; | ||
}); | ||
} | ||
|
||
public ValidTransaction peek() { | ||
return transactionQueue.peek(); | ||
} | ||
|
||
public ValidTransaction[] pending() { | ||
return transactionQueue.toArray(new ValidTransaction[0]); | ||
} | ||
|
||
public ValidTransaction[] pendingInPool() { | ||
return transactionPool.transactions(); | ||
} | ||
|
||
public boolean exists(ValidTransaction validTransaction) { | ||
return transactionQueue.contains(validTransaction); | ||
} | ||
|
||
public void removeExtrinsic(byte[] extrinsic) { | ||
transactionPool.removeExtrinsic(extrinsic); | ||
ValidTransaction transactionToBeRemoved = new ValidTransaction(extrinsic); | ||
transactionQueue.remove(transactionToBeRemoved); | ||
} | ||
|
||
public void removeExtrinsicFromPool(byte[] extrinsic) { | ||
transactionPool.removeExtrinsic(extrinsic); | ||
} | ||
|
||
public byte[] addToPool(ValidTransaction validTransaction) { | ||
return transactionPool.insert(validTransaction); | ||
} | ||
|
||
//public void notifyStatus | ||
ablax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.limechain.network.protocol.transaction.state; | ||
|
||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Comparator; | ||
|
||
@EqualsAndHashCode(onlyExplicitlyIncluded = true) | ||
public class ValidTransaction implements Comparable<ValidTransaction> { | ||
@Getter | ||
@EqualsAndHashCode.Include | ||
private final byte[] extrinsic; | ||
@Getter | ||
private Validity validity; | ||
|
||
public ValidTransaction(byte[] extrinsic){ | ||
this.extrinsic = extrinsic; | ||
} | ||
|
||
public ValidTransaction(byte[] extrinsic, Validity validity){ | ||
this.extrinsic = extrinsic; | ||
this.validity = validity; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space before opening curly brace |
||
|
||
public int compareTo(@NotNull ValidTransaction transaction) { | ||
return new ValidTransactionComparator().compare(this, transaction); | ||
} | ||
|
||
static class ValidTransactionComparator implements Comparator<ValidTransaction> { | ||
ablax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public int compare(ValidTransaction validTransaction, ValidTransaction otherValidTransaction) { | ||
return validTransaction.getValidity().getPriority() | ||
.compareTo(otherValidTransaction.getValidity().getPriority()); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.limechain.network.protocol.transaction.state; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
import java.math.BigInteger; | ||
|
||
@Getter | ||
@Setter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class Validity { | ||
private BigInteger priority; | ||
private byte[][] requires; | ||
private byte[][] provides; | ||
private BigInteger longevity; | ||
private boolean propagate; | ||
|
||
public Validity(BigInteger priority){ | ||
this.priority = priority; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment explaining what this class represents and how the priority works. If I have priority 1 and someone else has 18, am I with a higher priority or not? Also how are the negative cases handled? Would be nice to have a test for that case as well. |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add TODO to replace empty transaction messages in future