Skip to content

Commit

Permalink
Fixed transaction get empty transansaction when snapshot the transact…
Browse files Browse the repository at this point in the history
…ionpool with the transactions have the same timestamp
  • Loading branch information
AionJayT committed May 21, 2019
1 parent 600c942 commit 7444cee
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 24 deletions.
9 changes: 9 additions & 0 deletions modAion/src/org/aion/zero/types/AionTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.aion.util.bytes.ByteUtil.ZERO_BYTE_ARRAY;

import com.google.common.annotations.VisibleForTesting;
import java.math.BigInteger;
import java.util.Arrays;
import org.aion.mcf.vm.types.DataWordImpl;
Expand Down Expand Up @@ -343,6 +344,14 @@ public void sign(ECKey key) throws MissingPrivateKeyException {
this.rlpEncoded = null;
}


@VisibleForTesting
public void signWithSecTimeStamp(ECKey key) throws MissingPrivateKeyException {
this.timeStamp = ByteUtil.longToBytes(TimeInstant.now().toEpochSec() * 1_000_000L);
this.signature = key.sign(this.getRawHash());
this.rlpEncoded = null;
}

@Override
public String toString() {
return toString(Integer.MAX_VALUE);
Expand Down
3 changes: 2 additions & 1 deletion modTxPoolImpl/src/org/aion/txpool/zero/TxPoolA0.java
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,8 @@ public List<TX> snapshot() {
for (Entry<ByteArrayWrapper, TxDependList<ByteArrayWrapper>> pair :
e.getValue().entrySet()) {
BigInteger ts = pair.getValue().getTimeStamp();
while (timeTxDep.get(ts.add(BigInteger.ONE)) != null) {
// If timestamp has collision, increase 1 for getting a new slot to put the transaction pair.
while (timeTxDep.get(ts) != null) {
ts = ts.add(BigInteger.ONE);
}
timeTxDep.put(ts, pair);
Expand Down
107 changes: 84 additions & 23 deletions modTxPoolImpl/test/org/aion/txpool/test/TxnPoolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import org.aion.crypto.ECKeyFac;
import org.aion.txpool.ITxPool;
import org.aion.txpool.zero.TxPoolA0;
import org.aion.types.ByteArrayWrapper;
import org.aion.types.Hash256;
import org.aion.zero.types.AionTransaction;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
Expand Down Expand Up @@ -479,8 +481,9 @@ public void snapshot9() {
TxPoolA0<Transaction> tp = new TxPoolA0<>(config);

List<Transaction> txnl = new ArrayList<>();
Map<ByteArrayWrapper, Transaction> txMap = new HashMap<>();

int cnt = 25;
// Random r = new Random();
for (int i = 0; i < cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Expand All @@ -489,6 +492,7 @@ public void snapshot9() {
((AionTransaction) txn).sign(key.get(0));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}
tp.add(txnl);
assertTrue(tp.size() == cnt);
Expand All @@ -502,6 +506,7 @@ public void snapshot9() {
((AionTransaction) txn).sign(key.get(1));
txn.setNrgConsume(1);
txnl2.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}
tp.add(txnl2);
assertTrue(tp.size() == cnt * 2);
Expand All @@ -511,21 +516,9 @@ public void snapshot9() {
assertTrue(tp.size() == txl.size());
assertTrue(tp.snapshotAll().size() == txl.size());

int check = 0;
for (Transaction tx : txl) {
if (check < 25) {
assertTrue(
Hash256.wrap(txnl.get(check).getTransactionHash())
.toString()
.equals(Hash256.wrap(tx.getTransactionHash()).toString()));
check++;
} else {
assertTrue(
Hash256.wrap(txnl2.get(check - 25).getTransactionHash())
.toString()
.equals(Hash256.wrap(tx.getTransactionHash()).toString()));
check++;
}
assertTrue(txMap.containsKey(ByteArrayWrapper.wrap(tx.getTransactionHash())));
Assert.assertEquals(txMap.get(ByteArrayWrapper.wrap(tx.getTransactionHash())), tx);
}
}

Expand All @@ -537,8 +530,8 @@ public void snapshot10() {
TxPoolA0<Transaction> tp = new TxPoolA0<>(config);

List<Transaction> txnl = new ArrayList<>();
Map<ByteArrayWrapper, Transaction> txMap = new HashMap<>();
int cnt = 16;
// Random r = new Random();
for (int i = 0; i < cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Expand All @@ -547,6 +540,7 @@ public void snapshot10() {
((AionTransaction) txn).sign(key.get(0));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 0; i < cnt; i++) {
Expand All @@ -557,6 +551,7 @@ public void snapshot10() {
((AionTransaction) txn).sign(key.get(1));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 16; i < 16 + cnt; i++) {
Expand All @@ -567,6 +562,7 @@ public void snapshot10() {
((AionTransaction) txn).sign(key.get(0));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 16; i < 16 + cnt; i++) {
Expand All @@ -577,6 +573,7 @@ public void snapshot10() {
((AionTransaction) txn).sign(key.get(1));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

tp.add(txnl);
Expand All @@ -587,13 +584,77 @@ public void snapshot10() {
assertTrue(tp.size() == txl.size());
assertTrue(tp.snapshotAll().size() == txl.size());

int check = 0;
for (Transaction tx : txl) {
assertTrue(
Hash256.wrap(txnl.get(check).getTransactionHash())
.toString()
.equals(Hash256.wrap(tx.getTransactionHash()).toString()));
check++;
assertTrue(txMap.containsKey(ByteArrayWrapper.wrap(tx.getTransactionHash())));
Assert.assertEquals(txMap.get(ByteArrayWrapper.wrap(tx.getTransactionHash())), tx);
}
}

@Test
public void snapshotWithSameTransactionTimestamp() {
Properties config = new Properties();
config.put("tx-timeout", "100");

TxPoolA0<Transaction> tp = new TxPoolA0<>(config);

List<Transaction> txnl = new ArrayList<>();
Map<ByteArrayWrapper, Transaction> txMap = new HashMap<>();
int cnt = 16;
for (int i = 0; i < cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Transaction txn = genTransaction(nonce, 0);

((AionTransaction) txn).signWithSecTimeStamp(key.get(0));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 0; i < cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Transaction txn = genTransaction(nonce, 1);

((AionTransaction) txn).signWithSecTimeStamp(key.get(1));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 16; i < 16 + cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Transaction txn = genTransaction(nonce, 0);

((AionTransaction) txn).signWithSecTimeStamp(key.get(0));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

for (int i = 16; i < 16 + cnt; i++) {
byte[] nonce = new byte[Long.BYTES];
nonce[Long.BYTES - 1] = (byte) i;
Transaction txn = genTransaction(nonce, 1);

((AionTransaction) txn).signWithSecTimeStamp(key.get(1));
txn.setNrgConsume(1);
txnl.add(txn);
txMap.put(ByteArrayWrapper.wrap(txn.getTransactionHash()), txn);
}

tp.add(txnl);
assertTrue(tp.size() == cnt * 4);

// sort the inserted txs
List<Transaction> txl = tp.snapshot();
assertTrue(tp.size() == txl.size());
assertTrue(tp.snapshotAll().size() == txl.size());

for (Transaction tx : txl) {
assertTrue(txMap.containsKey(ByteArrayWrapper.wrap(tx.getTransactionHash())));
Assert.assertEquals(txMap.get(ByteArrayWrapper.wrap(tx.getTransactionHash())), tx);
}
}

Expand Down Expand Up @@ -820,7 +881,7 @@ public void feemapTest() {
int cnt = 100;
byte[] nonce = new byte[Long.BYTES];
for (int i = 0; i < cnt; i++) {
nonce[Long.BYTES - 1] = 1;
nonce[Long.BYTES - 1] = (byte) i;

Address addr = Address.wrap(key2.get(i).getAddress());
Transaction txn =
Expand Down

0 comments on commit 7444cee

Please sign in to comment.