Arbitrary Transaction support + various fixes

NOTE: requires HSQLDB built from svn rev 5836 or later

Fixed BuyNameTransactionData constructors not picking up nameReference.

Added new "orphan" tool to regress blockchain back to specified block.

Added new Block constructor for when receiving a block from the network.
Fixed Block generatingBalance/forging code to be compliant with v1.
Added logging of transactions that fail validation during block validation.

Fixed buyer/seller balances not being updated during name purchase.

Generally replace BigDecimal.compareTo expressions with "<operator> 0" form.
e.g. instead of someBigDecimal.compareTo(anotherBigDecimal) == 1
we now have someBigDecimal.compareTo(anotherBigDecimal) > 0

Fix amounts involved in BuyNameTransactions.

Renamed Transaction.calcSignature to .sign

Refactored Transaction.toBytesLessSignature to TransactionTransformer.toBytesForSigning,
which itself calls subclass' toBytesForSigningImpl,
which might override Transaction.toBytesForSigningImpl when special v1 mangling is required.

Corrected more cases of NTP.getTime in transaction processing
which should really be transaction's timestmap instead.

Fixed HSQLDB-related issue where strings were padded with spaces during comparison.
Some column types no longer case-insensitive as that mode of comparison
is done during transaction validation.

Added missing option_index column to CreatePollTransactionOptions which was causing
out-of-order options during fetching from repository and hence signature failures.

Added unit tests for v1-special mangled transaction signature checking.

Removed checks for remaining bytes to ByteBuffer in various transaction transformers'
fromByteBuffer() methods as the buffer underflow exception is now caught in
TransactionTransformer.fromBytes.

Corrected byte-related transformations of CreatePollTransactions that were missing
voter counts (albeit always zero).

Corrected byte-related transformations of IssueAssetTransactions that were missing
duplicate signature/reference (v1-special).

Added "txhex" tool to output transaction in hex form, given base58 tx signature.

Added "v1feeder" tool to fetch blocks from v1 node and process them.
This commit is contained in:
catbref
2018-08-02 10:02:33 +01:00
parent b401adcc55
commit 7da84b2b85
52 changed files with 1650 additions and 286 deletions

View File

@@ -10,7 +10,7 @@ import repository.hsqldb.HSQLDBRepositoryFactory;
public class Common {
public static final String connectionUrl = "jdbc:hsqldb:file:db/test;create=true;close_result=true;sql.strict_exec=true;sql.enforce_names=true;sql.syntax_mys=true";
public static final String connectionUrl = "jdbc:hsqldb:file:db/test;create=true;close_result=true;sql.strict_exec=true;sql.enforce_names=true;sql.syntax_mys=true;sql.pad_space=false";
@BeforeClass
public static void setRepository() throws DataException {

View File

@@ -0,0 +1,67 @@
package test;
import static org.junit.Assert.*;
import org.junit.Test;
import com.google.common.hash.HashCode;
import data.transaction.TransactionData;
import qora.transaction.CreateOrderTransaction;
import qora.transaction.CreatePollTransaction;
import qora.transaction.IssueAssetTransaction;
import transform.TransformationException;
import transform.transaction.TransactionTransformer;
public class CompatibilityTests {
@Test
public void testCreateOrderTransactionSignature() throws TransformationException {
// 4EsGzQ87rXqXw2nic8LiihGCrM5iNErK53u9TRo2AJv4FWWyCK7bUKrCmswnrBbkB7Dsk7wfzi9hM2TGGqm6LVpd
byte[] rawTx = HashCode
.fromString("0000000d" + "000001489be3ef8e"
+ "10b52b229c73afb40a56df4f1c9f65072041011cf9ae25a053397d9fc5578bc8f1412eb404de4e318e24302863fc52889eb848af65a6b17cfc964267388f5802"
+ "bf497fa72ed16894f3acab6c4a101fd8b5fd42f0420dad45474388d5492d38d0" + "0000000000000000" + "0000000000000001"
+ "000000000000000005f5e100" + "000000000000000005f5e100" + "0000000005f5e100"
+ "a2025bfde5c90254e16150db6aef6189bb2856df51940b6a15b1d5f174451236062c982af4da3429941337abc7002a862782fb9c726bfc95aea31e30bf66a502")
.asBytes();
TransactionData transactionData = TransactionTransformer.fromBytes(rawTx);
CreateOrderTransaction transaction = new CreateOrderTransaction(null, transactionData);
assertTrue(transaction.isSignatureValid());
}
@Test
public void testCreatePollTransactionSignature() throws TransformationException {
// 5xo8YxDVTFVR1pdmtxYkRbq3PkcKVttyH7wCVAfgqokDMKE1XW6zrqFgJG8vRQz9qi5r8cqBoSgFKLnQRoSyzpgF
byte[] rawTx = HashCode
.fromString("00000008" + "00000146d4237f03"
+ "c201817ee2d4363801b63cbe154f6796719feb5a9673758dfda7b5e616cddd1263bbb75ce6a14ca116abe2d34ea68f353379d0c0d48da62180677053792f3b00"
+ "ef893a99782612754157d868fc4194577cca8ca5dd264c90855829f0e4bbec3a" + "3a91655f3c70d7a38980b449ccf7acd84de41f99dae6215ed5" + "0000000a"
+ "746869736973706f6c6c" + "00000004" + "74657374" + "00000002" + "00000011" + "546869732069732073706f6e6765626f62" + "00000000"
+ "0000000f" + "54686973206973207061747269636b" + "00000000" + "0000000005f5e100"
+ "f82f0c7421333c2cae5d0d0200e7f4726cda60baecad4ba067c7da17c681e2fb20612991f75763791b228c258f79ec2ecc40788fdda71b8f11a9032417ec7e08")
.asBytes();
TransactionData transactionData = TransactionTransformer.fromBytes(rawTx);
CreatePollTransaction transaction = new CreatePollTransaction(null, transactionData);
assertTrue(transaction.isSignatureValid());
}
@Test
public void testIssueAssetTransactionSignature() throws TransformationException {
// 3JeJ8yGnG8RCQH51S2qYJT5nfbokjHnBmM7KZsj61HPRy8K3ZWkGHh99QQ6HbRHxnknnjjAsffHRaeca1ap3tcFv
byte[] rawTx = HashCode
.fromString(
"0000000b000001489376bea34d4cbdb644be00b5848a2beeee087fdb98de49a010e686de9540f7d83720cdd182ca6efd1a6225f72f2821ed8a19f236002aef33afa4e2e419fe641c2bc4800a8dd3440f3ce0526c924f2cc15f3fdc1afcf4d57e4502c7a13bfed9851e81abc93a6a24ae1a453205b39d0c3bd24fb5eb675cd199e7cb5b316c00000003787878000000117878787878787878787878787878787878000000000000006400733fa8fa762c404ca1ddd799e93cc8ea292cd9fdd84d5c8b094050d4f576ea56071055f9fe337bf610624514f673e66462f8719759242b5635f19da088b311050000000005f5e100733fa8fa762c404ca1ddd799e93cc8ea292cd9fdd84d5c8b094050d4f576ea56071055f9fe337bf610624514f673e66462f8719759242b5635f19da088b31105")
.asBytes();
TransactionData transactionData = TransactionTransformer.fromBytes(rawTx);
IssueAssetTransaction transaction = new IssueAssetTransaction(null, transactionData);
assertTrue(transaction.isSignatureValid());
}
}

View File

@@ -148,7 +148,7 @@ public class TransactionTests {
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(sender.getPublicKey(), recipient, amount, fee, timestamp, reference);
Transaction paymentTransaction = new PaymentTransaction(repository, paymentTransactionData);
paymentTransaction.calcSignature(sender);
paymentTransaction.sign(sender);
return paymentTransaction;
}
@@ -166,7 +166,7 @@ public class TransactionTests {
reference);
Transaction paymentTransaction = new PaymentTransaction(repository, paymentTransactionData);
paymentTransaction.calcSignature(sender);
paymentTransaction.sign(sender);
assertTrue(paymentTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, paymentTransaction.isValid());
@@ -227,7 +227,7 @@ public class TransactionTests {
timestamp, reference);
Transaction registerNameTransaction = new RegisterNameTransaction(repository, registerNameTransactionData);
registerNameTransaction.calcSignature(sender);
registerNameTransaction.sign(sender);
assertTrue(registerNameTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, registerNameTransaction.isValid());
@@ -283,7 +283,7 @@ public class TransactionTests {
nameReference, fee, timestamp, reference);
Transaction updateNameTransaction = new UpdateNameTransaction(repository, updateNameTransactionData);
updateNameTransaction.calcSignature(sender);
updateNameTransaction.sign(sender);
assertTrue(updateNameTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, updateNameTransaction.isValid());
@@ -328,7 +328,7 @@ public class TransactionTests {
SellNameTransactionData sellNameTransactionData = new SellNameTransactionData(sender.getPublicKey(), name, amount, fee, timestamp, reference);
Transaction sellNameTransaction = new SellNameTransaction(repository, sellNameTransactionData);
sellNameTransaction.calcSignature(sender);
sellNameTransaction.sign(sender);
assertTrue(sellNameTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, sellNameTransaction.isValid());
@@ -379,7 +379,7 @@ public class TransactionTests {
CancelSellNameTransactionData cancelSellNameTransactionData = new CancelSellNameTransactionData(sender.getPublicKey(), name, fee, timestamp, reference);
Transaction cancelSellNameTransaction = new CancelSellNameTransaction(repository, cancelSellNameTransactionData);
cancelSellNameTransaction.calcSignature(sender);
cancelSellNameTransaction.sign(sender);
assertTrue(cancelSellNameTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, cancelSellNameTransaction.isValid());
@@ -445,7 +445,7 @@ public class TransactionTests {
nameReference, fee, timestamp, buyersReference);
Transaction buyNameTransaction = new BuyNameTransaction(repository, buyNameTransactionData);
buyNameTransaction.calcSignature(buyer);
buyNameTransaction.sign(buyer);
assertTrue(buyNameTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, buyNameTransaction.isValid());
@@ -498,7 +498,7 @@ public class TransactionTests {
description, pollOptions, fee, timestamp, reference);
Transaction createPollTransaction = new CreatePollTransaction(repository, createPollTransactionData);
createPollTransaction.calcSignature(sender);
createPollTransaction.sign(sender);
assertTrue(createPollTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, createPollTransaction.isValid());
@@ -552,7 +552,7 @@ public class TransactionTests {
reference);
Transaction voteOnPollTransaction = new VoteOnPollTransaction(repository, voteOnPollTransactionData);
voteOnPollTransaction.calcSignature(sender);
voteOnPollTransaction.sign(sender);
assertTrue(voteOnPollTransaction.isSignatureValid());
if (optionIndex == pollOptionsSize) {
@@ -624,7 +624,7 @@ public class TransactionTests {
quantity, isDivisible, fee, timestamp, reference);
Transaction issueAssetTransaction = new IssueAssetTransaction(repository, issueAssetTransactionData);
issueAssetTransaction.calcSignature(sender);
issueAssetTransaction.sign(sender);
assertTrue(issueAssetTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, issueAssetTransaction.isValid());
@@ -714,7 +714,7 @@ public class TransactionTests {
assetId, fee, timestamp, reference);
Transaction transferAssetTransaction = new TransferAssetTransaction(repository, transferAssetTransactionData);
transferAssetTransaction.calcSignature(sender);
transferAssetTransaction.sign(sender);
assertTrue(transferAssetTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, transferAssetTransaction.isValid());
@@ -818,7 +818,7 @@ public class TransactionTests {
CreateOrderTransactionData createOrderTransactionData = new CreateOrderTransactionData(buyer.getPublicKey(), haveAssetId, wantAssetId, amount, price,
fee, timestamp, buyersReference);
Transaction createOrderTransaction = new CreateOrderTransaction(this.repository, createOrderTransactionData);
createOrderTransaction.calcSignature(buyer);
createOrderTransaction.sign(buyer);
assertTrue(createOrderTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, createOrderTransaction.isValid());
@@ -899,7 +899,7 @@ public class TransactionTests {
CancelOrderTransactionData cancelOrderTransactionData = new CancelOrderTransactionData(buyer.getPublicKey(), orderId, fee, timestamp, buyersReference);
Transaction cancelOrderTransaction = new CancelOrderTransaction(this.repository, cancelOrderTransactionData);
cancelOrderTransaction.calcSignature(buyer);
cancelOrderTransaction.sign(buyer);
assertTrue(cancelOrderTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, cancelOrderTransaction.isValid());
@@ -970,7 +970,7 @@ public class TransactionTests {
CreateOrderTransactionData createOrderTransactionData = new CreateOrderTransactionData(sender.getPublicKey(), haveAssetId, wantAssetId, amount, price,
fee, timestamp, reference);
Transaction createOrderTransaction = new CreateOrderTransaction(this.repository, createOrderTransactionData);
createOrderTransaction.calcSignature(sender);
createOrderTransaction.sign(sender);
assertTrue(createOrderTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, createOrderTransaction.isValid());
@@ -1073,7 +1073,7 @@ public class TransactionTests {
MultiPaymentTransactionData multiPaymentTransactionData = new MultiPaymentTransactionData(sender.getPublicKey(), payments, fee, timestamp, reference);
Transaction multiPaymentTransaction = new MultiPaymentTransaction(repository, multiPaymentTransactionData);
multiPaymentTransaction.calcSignature(sender);
multiPaymentTransaction.sign(sender);
assertTrue(multiPaymentTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, multiPaymentTransaction.isValid());
@@ -1143,7 +1143,7 @@ public class TransactionTests {
data, isText, isEncrypted, fee, timestamp, reference);
Transaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
messageTransaction.calcSignature(sender);
messageTransaction.sign(sender);
assertTrue(messageTransaction.isSignatureValid());
assertEquals(ValidationResult.OK, messageTransaction.isValid());