Added CreatePollTransactionData constructor that doesn't need signature (for creating new transactions).
Added missing "published" timestamp support to PollData and Poll.
Removed extraneous timestamp test from Block.isValid.
Corrected inconsistent column names in poll-related tables in HSQLDBDatabaseUpdates.
HSQLDBRepository.checkedExecute(PreparedStatement) now takes extra Object... params
so that values can be bound to placeholders. Code moved from checkedExecute(String, Object...).
This fixes an issue with exists(String, String, Object...) where placeholders weren't having
any values bound to them. (Also removed "ORDER BY NULL" clause which isn't supported by HSQLDB).
HSQLDBVotingRepository method stubs fleshed out with real code.
TransactionTests rejigged but more work needed to test various transactions before/after their feature
release. e.g. testing create poll transactions before & after they supposedly went live.
Could do with a GenesisBlock constructor that takes a timestamp for testing purposes?
CreatePollTransactionTransformer now skips serializing a null signature,
in the same way PaymentTransactionTransformer does, to aid getBytesLessSignature().
This will probably need to be rolled out to all other transaction types.
* Replaced occurances of "this.repository.getResultSetBytes(resultSet.getBinaryStream(index))"
with "resultSet.getBytes(index)"
* Replaced corresponding preparedStatement.setBinaryStream() with preparedStatement.setBytes()
* Fixed migrate app so DB can be rebuilt using old v1 Qora client
* Moved Asset issue/deissue code from IssueAssetTransaction to Asset business object.
* Added more constructors for Asset using IssueAssetTransactionData or assetId.
* Moved some constants from transaction transfers to business objects (e.g. IssueAssetTransaction)
(They might now make more sense being in Asset)
* Changed some transaction isValid() checks to use transaction's timestamp instead of NTP.getTime()
* New VotingRepository - as yet unimplemented
Really need to rewrite "migrate" and add a ton of unit tests.
* Add implementation for Account.getBalance(assetId, numberOfConfirmations)
* Added orphan() code to Block (CIYAM AT not yet supported)
* Added getOrder() 'navigation' method to CreateOrderTransaction
* Added missing transaction-type cases to various switches in Transaction, transformers, repositories, etc.
* Various repository delete() methods added
* Added save/delete support for transaction types that include payments, like multipayment and arbitrary
* Changed "recipient" in HSQLDB SharedTransactionPayments from QoraPublicKey to QoraAddress
* Code added for calculating an account's generating balance. (CIYAM AT support yet to be added).
* Added associated code in Block for calculating next block's timestamp, generating balance, base target, etc.
* ValidationResult enum added to Block, mostly to aid debugging.
* Block.isValid() now returns ValidationResult instead of boolean.
* Block.isValid() now has added proof-of-stake tests.
* Some blockchain-related constants, like feature release heights/timestamps, moved from Block to BlockChain.
* Added better Block constructor for use when creating a new block.
* Added helpful 'navigation' methods to Block to get to block's parent (or child).
* Changed visibility of block's individual signature calculators to protected, in favour of public sign() method.
* Added asset existence check to Payment.isValid.
* All current transaction objects (qora.transaction.*) now have private subclassed transaction variable to save multiple casts in various methods.
* Also added to above:
* isInvolved(Account) : boolean
* getRecipients() : List<Account>
* getAmount(Account) : BigDecimal
* Added BlockRepository.getLastBlock() to fetch highest block in blockchain.
* Added diagnostics to HSQLDBRepository.close() to alert if there are any uncommitted changes during closure.
(Currently under suspicion due to possible HSQLDB bug!)
* Old "TransactionTests" renamed to "SerializationTests" as that's what they really are.
* New "TransactionTests" added to test processing of transactions. (Currently only a PaymentTransaction).
* PaymentTransformer.toBytes() detects and skips null signature. This was causing issues with Transaction.toBytesLessSignature().
Needs rolling out to other transaction types if acceptable.
* Created PaymentData transfer objects for (recipient, assetId, amount) tuples
* Created corresponding Payment class for validating, processing and orphaning payment(s)
* Modified OrderData to support isClosed for when an Order is cancelled so no more trades can occur
* Migrated CancelOrderTransactions and MultiPaymentTransactions
* Converted MessageTransactions, PaymentTransactions and TransferAssetTransactions to use new Payment class
Can't use PaymentTransformer in PaymentTransformer or TransferAssetTransformer due to serialization differences.
* Added AssetData transfer object
* Added IssueAssetTransactionData transfer object
* Reworked qora.assets.Asset into business layer object
* Reworked qora.transaction.IssueAssetTransaction into business layer object
* Added corresponding AssetRepository and support in TransactionRepository et al
* Fixed BlockChain in line with asset changes
* Some renaming inside GenesisTransaction to reflect use of transfer object, not business object
* Business transaction objects now take Repository param
* Moved HSQLDB transaction repositories into a sub-package
* Changed HSQLDBSaver.execute(Connection connection) to .execute(Repository repository) to fix visibility issues
and allow repository more control in the future if need be
* Changed from "return null" statements in HSQLDB repositories to throw DataException when an error occurs.
Better to throw than to silently return null?
* Added static version of PublicKeyAccount.verify() for when a repository-backed PublicKeyAccount is not needed
* Fixed getter/setter code template incorrectly producing "this.this.field = param"
Moved more repository-like methods from qora.* classes to repository.
Removed qora.block.BlockTransaction as it's pretty much internal to the HSQLDB repository.
Fixing qora.account.*
Fixing genesis-related classes: block, account, transaction...
Rolled BlockTransactionRepository into BlockRepository.
Added AccountRepository for general account info and account balances.
BlockTransformer now takes Block as param instead of BlockData as it needs Block's transactions.
No need for database.DB class as the code is specific to HSQLDB so moved into relevant repository.hsqldb classes.
Top-level Repository instance (e.g. HSQLDBRepository) is used within subclasses, e.g. HSQLDBBlockRepository, so they
can share the same repository state, like underlying SQL Connection for easier transactional support.
HSQLDBRepository subclasses now call checkedExecute() on top-level repository instance, instead of passing Connection
to obsolete DB.checkedExecute.
No need for qora.block.BlockFactory any more as those methods are now in repository.
More work on Blocks and Transactions in general.
Still converting to repository layout.
This commit is just in case my dev computer blows up and also for interim code review.
Removed data.block.BlockData as an interface (with data.block.Block as implementation) for now.
added data access class for block
added HSQLDB repository with reader methods for block data
started usage of repository and data objects in BlockFactory
qora.* packages are business logic/handler/processing
data.* packages are "value objects" or are they "business objects"?
toBytes(), fromBytes() (which used to be called parse()) and toJSON() moved to transform.* packages
new issues:
Lost control of SQL Transactions. Previously, some class "knew" whether to call COMMIT or not.
e.g. simply saving a payment transaction would involve updating Transactions table first, then the PaymentTransactions table after (to satisfy foreign key constraints) then commit.
Processing a block would involve a new transaction, a savepoint, a rollback and then maybe a further commit or rollback.
Not sure how this is going to work with the repository, especially if business logic isn't supposed to be aware of such things.
Growing number of stupid try-catch blocks. Probably best to ditch TransformationException (was ParseException) and throw IllegalStateExceptions instead as they're "unchecked".
What happens if the repository fails to save() to the database? It can't throw SQLException any more as that has no meaning outside the repository. Ditto with delete().
Much tidier code thanks to not having to pass Connection objects around
as params. Also no need for two forms of the same method, one with Connection
param, one without.
Also corrected SQL-Transaction-related methods in DB, e.g. commit, rollback, etc.
so they use the proper underlying JDBC methods.
Use HSQLDB "CREATE TYPE" instead of "CREATE DOMAIN" as collate clause is lost on HSQLDB shutdown in v2.4.0.
Restore GenesisAccount's public key back to 8-byte legacy value.
More work on block/transaction processing.
It's becoming apparent that way too many Connection objects are being passed around, and now with two forms of
methods (one with, one without) it's time to switch to something like thread-local Connections.
Maybe also switch to having data access objects.
So this commit is save work prior to that conversion.
Added Apache commons-net as maven dependency for NTP support.
Added SAVEPOINT and ROLLBACK TO SAVEPOINT support to DB class.
Added exists() test to DB class.
Add MessageTransactions, with V1/V3 code in one class instead of very similar code
split across two classes. Update DB schema to add version.
More fleshing out of Assets class.
Fleshing out Block class with parse(), generating balance and signature-related methods.
More javadoc. More tests.
No need for DB.executeUsingBytes as it was only a specific use-case for DB.checkedExecute.
Callers now refactored to use DB.checkedExecute instead.
Minor tidying up of BlockTransactions in light of above.
In the HSQLDB database, asset keys/IDs are now "asset_id" (previously: "asset").
Added initial Asset/Order/Trade classes.
Added CreateOrderTransaction class.
Renamed some asset-related fields back to old gen1 names, e.g. haveAmount -> amount, wantAmount -> price.
Added Accounts and AccountBalances to database.
Added get/set confirmed balance support to Account.
Added get/set last reference support to Account.
Added Block.toJSON() - untested at this time.
Fleshed out some Transaction sub-classes' process() and orphan() methods.
Fleshed out PaymentTransaction.isValid().
Added Transaction.delete() - untested.
DB.rebuild() to shutdown and delete database, then rebuild it (schema only).
DB.callIdentity() to fetch value of IDENTITY column after an INSERT.
Added basic Asset class.
Added TODOs to Account.
BULK REFACTOR to rename "generation target" back to "generating balance" and
"generation signature" back to "generator signature" to ease compatibility with
old QORA for now. (Maybe change again in the future if we change from PoS).
Added support for Block's totalFees which is either loaded from DB
or recalculated as transactions are added to the block.
Also in Block:
* We can't assume generator's public key is the correct length
in case we encounter the GenesisAccount's special 8-byte public key. Fix applied to
Block's ResultSet-based constructor.
* Forgot to save "signature" column!
* Initial version of Block.process()
* Block constructor takes transactionsSignature too now
Added BlockChain startup/init/validation method to determine whether to (re)build blockchain.
Rebuilding blockchain involves rebuilding DB schema, processing GenesisBlock and adding QORA asset.
Added some initial GenesisTranaction.process() code: GenesisTransactions are saved but recipient's balance/reference not yet updated.
Fix incorrect placeholder bind value for "creation" timestamp in Transaction.save().
Moved incremental database schema updates out from "updates" unit test into DatabaseUpdates class.
All unit tests work at this point!
Add Transaction.parse() support. Subclasses are called, switched by transaction type,
using ByteBuffer.
Correct RECIPIENT_LENGTH in Transaction.
Common [de]serialization tasks moved to methods in Serialization class.
Too many calls needing Connection object in args when they're only
simple database reads. Even worse, some methods had database-less
counterparts with different outputs, e.g. toJSON().
Now Connections can be requested from the pool for general database
read scenarios. Code paths that might perform a multi-statement
database transaction still require a Connection arg passed around
as the database transaction are local to that Connection.
In light of above, added support for database opening, closing,
setting URL.
Fixed out of bounds array index bug in unknown-length version of DB.getResultSetBytes().
Fixed Block's lazy-instantiation of Transactions.
Implemented Block's isSignatureValid().
Fixed bug in Crypto.isValidAddress() which was using the wrong bytes.
Fix GenesisTransaction generic constructor calling super with PaymentTransaction type!
Fix GenesisTransaction signature constructor using wrong column indexes from ResultSet.
In Transaction, don't expect CREATOR_LENGTH bytes from database in case we're dealing
with a GenesisTransaction where the creator's public key is only 8 bytes long.
Improvements to unit tests, including changing migrate so it can be run repeatedly to do
incremental migrations.
PaymentTransaction now uses Account for recipient internally but maybe should extend that type change to constructor args.
GenesisBlock added also with signature test.
More javadocs.
Added brokenmd160.java as command-line support for producing broken MD160 digests.
Transactions, and sub-classes, now use/store public key instead of Qora address.
(Qora address can be derived from public key and they take up about the same space in DB).
Loads more JavaDoc for lovely mouseover help in Eclipse IDE.
Crypto.verify() and Crypto.sign() moved into PublicKeyAccount and PrivateKeyAccount
as appropriate.
Fleshed out Block, added BlockTransactions support.
Added TODO comments as Eclipse helpfully lists these for later implementation.
Made loading-from-DB-constructors protected/private and also throw NoDataFoundException
if unable to load from DB. Public methods can call respective constructors, catch the above
exception and return null if they like. Load-from-DB-constructors are to allow sub-classes
to load some data from sub-tables and super-class to load from another table.
(See PaymentTransaction/Transaction for example). Using public methods allows similar argument
lists but with different names,
e.g. DBObject.fromSignature(Connection, byte[]) and DBObject.fromReference(Connection, byte[])
Saving into DB maybe still a bit untidy. Looking for a way to close-couple column names with
place-holder bind Objects.
Less of:
connection.prepareStatement("INSERT INTO table (column) VALUES (?)")
DB.bindInsertPlaceholders(PreparedStatement, Object...);
More like:
DB.insertUpdate(String tableName, SomeMagicCloseCoupledPairs...)
called like:
DB.insertUpdate("Cats", {"name", "Tiddles"}, {"age", 3});
Most SQL tables defined but only payment transactions actually implemented.
Maven support added.
Some code imported from 'old' Qora:
RIPEMD160 renamed as BrokenMD160 and deprecated.
whispersystem's Ed25519 implementation (to be replaced with bouncycastle).
Basic Account/PublicKeyAccount/PrivateKeyAccount code.
Some utils like Base58 and Pair.
To use:
Use maven to fetch dependencies.
Build project.
Fire up an old-gen Qora node.
Run src/test/update.java as a JUnit test to build DB structure.
Run src/test/migrate.java as a JUnit test to migrate old Qora blocks to DB.
You should now be able to run src/test/load.java and src/test/save.java
as JUnit tests demonstrating loading/saving Transactions from/to database.
This commit done while halfway through adding Block support!