Unit test fixes + initial CIYAM AT integration

NB: we're still using HSQLDB svn r5836

Updated README.md

Added log4j2.properties file for logging!

Imported CIYAM-AT jar into project-local Maven repo
CIYAM-AT related:
ATData
ATStateData
ATTransactionData
DeployATTransactionData
AT
DeployATTransaction
ATRepository
HSQLDBATRepository
HSQLDBDeployATTransactionRepository
ATTests
DeployATTransactionTransformer

Fixed Block so correct block hash and timestamps are generated,
especially when previous/next block versions differ.
Added extra call in BlockTransformer to aid this.

Fixed GenesisTransaction.isValid's incorrect amount test.

Fixed comments in TransferAssetTransaction and incorrect use of BlockChain.getVotingReleaseTimestamp()
instead of BlockChain.getAssetsReleaseTimestamp().

Added new TYPEs to HSQLDBDatabaseUpdates, and set LOB granularity to 1KB for AT use.
Added AT_address column to DeployATTransactions in HSQLDB.
Added ATs, ATStates and ATTransactions tables.
(You will need to discard existing database and rebuild).

Fixed incorrect byte array output in IssueAssetTransactionTransformer,
where Asset "references" were not processed correctly.

Added support for BigDecimal serialization to a byte-array size other than the standard 8.
This commit is contained in:
catbref
2018-10-04 14:38:59 +01:00
parent 0aa0796f35
commit e9d8b3e6e3
40 changed files with 1393 additions and 54 deletions

96
src/test/ATTests.java Normal file
View File

@@ -0,0 +1,96 @@
package test;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.Arrays;
import org.junit.Test;
import com.google.common.hash.HashCode;
import data.block.BlockData;
import data.block.BlockTransactionData;
import data.transaction.DeployATTransactionData;
import qora.transaction.DeployATTransaction;
import repository.DataException;
import repository.Repository;
import repository.RepositoryManager;
import transform.TransformationException;
import utils.Base58;
public class ATTests extends Common {
@Test
public void testATAccount() throws TransformationException, DataException {
// 2dZ4megUyNoYYY7qWmuSd4xw1yUKgPPF97yBbeddh8aKuC8PLpz7Xvf3r6Zjv1zwGrR8fEAHuaztCPD4KQp76KdL at height 125598
// AT address: AaaUn82XV4YcUtsQ3rHa5ZgqyiK35rVfE3
String expectedAddress = "AaaUn82XV4YcUtsQ3rHa5ZgqyiK35rVfE3";
byte[] creatorPublicKey = HashCode.fromString("c74d71ecec6b37890f26573186e634986cc90a507af01749f92aa2c7c95ad05f").asBytes();
String name = "QORABURST @ 1.00";
String description = "Initiators BURST address: BURST-LKGW-Z2JK-EZ99-E7CUE";
String ATType = "acct";
String tags = "acct,atomic cross chain tx,initiate,initiator";
byte[] creationBytes = HashCode
.fromString("010000000100010000000000" + "0094357700" + "000000bf"
+ "3501030900000006040000000900000029302009000000040000000f1ab4000000330403090000003525010a000000260a000000320903350703090000003526010a0000001b0a000000cd322801331601000000003317010100000033180102000000331901030000003505020a0000001b0a000000a1320b033205041e050000001833000509000000320a033203041ab400000033160105000000331701060000003318010700000033190108000000320304320b033203041ab7"
+ "00000048"
+ "5e211280259d2f3130248482c2dfc53be2fd5f9bedc9bc21425f951e8097a21900000000c80000003ac8716ad810191acf270d22e9f47f27806256c10d6ba6144900000000000000")
.asBytes();
BigDecimal amount = BigDecimal.valueOf(500.0).setScale(8);
BigDecimal fee = BigDecimal.valueOf(20.0).setScale(8);
long timestamp = 1439997077932L;
byte[] reference = Base58.decode("2D3jX1pEgu6irsQ7QzJb85QP1D9M45dNyP5M9a3WFHndU5ZywF4F5pnUurcbzMnGMcTwpAY6H7DuLw8cUBU66ao1");
byte[] signature = Base58.decode("2dZ4megUyNoYYY7qWmuSd4xw1yUKgPPF97yBbeddh8aKuC8PLpz7Xvf3r6Zjv1zwGrR8fEAHuaztCPD4KQp76KdL");
DeployATTransactionData transactionData = new DeployATTransactionData(creatorPublicKey, name, description, ATType, tags, creationBytes, amount, fee,
timestamp, reference, signature);
try (final Repository repository = RepositoryManager.getRepository()) {
repository.getTransactionRepository().save(transactionData);
DeployATTransaction transaction = new DeployATTransaction(repository, transactionData);
// Fake entry for this transaction at block height 125598 if it doesn't already exist
if (transaction.getHeight() == 0) {
byte[] blockSignature = Base58.decode(
"2amu634LnAbxeLfDtWdTLiCWtKu1XM2XLK9o6fDM7yGNNoh5Tq2KxSLdx8AS486zUU1wYNGCm8mcGxjMiww979MxdPVB2PQzaKrW2aFn9hpdSNN6Nk7EmeYKwsZdx9tkpHfBt5thSrUUrhzXJju9KYCAP6p3Ty4zccFkaxCP15j332U");
byte[] generatorSignature = Arrays.copyOfRange(blockSignature, 0, 64);
byte[] transactionsSignature = Arrays.copyOfRange(blockSignature, 64, 128);
// Check block exists too
if (repository.getBlockRepository().fromSignature(blockSignature) == null) {
int version = 2;
byte[] blockReference = blockSignature;
int transactionCount = 0;
BigDecimal totalFees = BigDecimal.valueOf(70.0).setScale(8);
int height = 125598;
long blockTimestamp = 1439997158336L;
BigDecimal generatingBalance = BigDecimal.valueOf(1440368826L).setScale(8);
byte[] generatorPublicKey = Base58.decode("X4s833bbtghh7gejmaBMbWqD44HrUobw93ANUuaNhFc");
byte[] atBytes = HashCode.fromString("17950a6c62d17ff0caa545651c054a105f1c464daca443df846cc6a3d58f764b78c09cff50f0fd9ec2").asBytes();
BigDecimal atFees = BigDecimal.valueOf(50.0).setScale(8);
BlockData blockData = new BlockData(version, blockReference, transactionCount, totalFees, transactionsSignature, height, blockTimestamp,
generatingBalance, generatorPublicKey, generatorSignature, atBytes, atFees);
repository.getBlockRepository().save(blockData);
}
int sequence = 0;
BlockTransactionData blockTransactionData = new BlockTransactionData(blockSignature, sequence, signature);
repository.getBlockRepository().save(blockTransactionData);
}
String actualAddress = transaction.getATAccount().getAddress();
repository.discardChanges();
assertEquals(expectedAddress, actualAddress);
}
}
}

View File

@@ -2,6 +2,8 @@ package test;
import static org.junit.Assert.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import repository.DataException;
@@ -10,6 +12,8 @@ import repository.RepositoryManager;
public class RepositoryTests extends Common {
private static final Logger LOGGER = LogManager.getLogger(RepositoryTests.class);
@Test
public void testGetRepository() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
@@ -45,6 +49,8 @@ public class RepositoryTests extends Common {
fail();
} catch (NullPointerException | DataException e) {
}
LOGGER.warn("Expect \"repository already closed\" complaint below");
}
}

View File

@@ -27,6 +27,8 @@ public class SaveTests extends Common {
BigDecimal.ONE, Instant.now().getEpochSecond(), reference, signature);
repository.getTransactionRepository().save(paymentTransactionData);
repository.discardChanges();
}
}

View File

@@ -4,6 +4,7 @@ import static org.junit.Assert.*;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -616,7 +617,7 @@ public class TransactionTests {
String assetName = "test asset";
String description = "test asset description";
long quantity = 1_000_000L;
boolean isDivisible = false;
boolean isDivisible = true;
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
@@ -956,16 +957,20 @@ public class TransactionTests {
assertNotNull(originalOrderData);
assertFalse(originalOrderData.getIsClosed());
// Unfulfilled order: "buyer" has 10 QORA and wants to buy "test asset" at a price of 50 "test asset" per QORA.
// buyer's order: have=QORA, amount=10, want=test-asset, price=50 (test-asset per QORA, so max return is 500 test-asset)
// Original asset owner (sender) will sell asset to "buyer"
// Order: seller has 40 "test asset" and wants to buy QORA at a price of 1/60 QORA per "test asset".
// This order should be a partial match for original order, and at a better price than asked
long haveAssetId = Asset.QORA;
long haveAssetId = assetId;
BigDecimal amount = BigDecimal.valueOf(40).setScale(8);
long wantAssetId = assetId;
BigDecimal price = BigDecimal.ONE.setScale(8).divide(BigDecimal.valueOf(60).setScale(8));
long wantAssetId = Asset.QORA;
BigDecimal price = BigDecimal.ONE.setScale(8).divide(BigDecimal.valueOf(60).setScale(8), RoundingMode.DOWN);
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
BigDecimal senderPreTradeWantBalance = sender.getConfirmedBalance(wantAssetId);
CreateOrderTransactionData createOrderTransactionData = new CreateOrderTransactionData(sender.getPublicKey(), haveAssetId, wantAssetId, amount, price,
fee, timestamp, reference);
@@ -989,20 +994,19 @@ public class TransactionTests {
byte[] orderId = createOrderTransactionData.getSignature();
OrderData orderData = assetRepo.fromOrderId(orderId);
assertNotNull(orderData);
assertFalse(orderData.getIsFulfilled());
// Check order has trades
List<TradeData> trades = assetRepo.getOrdersTrades(orderId);
assertNotNull(trades);
assertEquals(1, trades.size());
assertEquals("Trade didn't happen", 1, trades.size());
TradeData tradeData = trades.get(0);
// Check trade has correct values
BigDecimal expectedAmount = amount.multiply(price);
BigDecimal expectedAmount = amount.divide(originalOrderData.getPrice()).setScale(8);
BigDecimal actualAmount = tradeData.getAmount();
assertTrue(expectedAmount.compareTo(actualAmount) == 0);
BigDecimal expectedPrice = originalOrderData.getPrice().multiply(amount);
BigDecimal expectedPrice = amount;
BigDecimal actualPrice = tradeData.getPrice();
assertTrue(expectedPrice.compareTo(actualPrice) == 0);
@@ -1017,10 +1021,17 @@ public class TransactionTests {
assertTrue(expectedBalance.compareTo(actualBalance) == 0);
// Check seller's QORA balance
expectedBalance = initialSenderBalance.subtract(BigDecimal.ONE).subtract(BigDecimal.ONE);
expectedBalance = senderPreTradeWantBalance.subtract(BigDecimal.ONE).add(expectedAmount);
actualBalance = sender.getConfirmedBalance(wantAssetId);
assertTrue(expectedBalance.compareTo(actualBalance) == 0);
// Check seller's order is correctly fulfilled
assertTrue(orderData.getIsFulfilled());
// Check buyer's order is still not fulfilled
OrderData buyersOrderData = assetRepo.fromOrderId(originalOrderData.getOrderId());
assertFalse(buyersOrderData.getIsFulfilled());
// Orphan transaction
block.orphan();
repository.saveChanges();