Performance fix & other minor fixes

Fixed bug in GenesisBlock which wasn't stripping
out ISSUE_ASSET transactions for v1 blockchains.

Updated blockchain.json for v1 qora blockchain to
fall into line with new BlockChain config
unmarshalling code.

Improved TransactionData.equals when comparing
exact same object.

Improved HSQLDBBlockRepository.getHeightFromTimestamp to use OffsetDateTime
object, which includes time zone info, to fix incorrect SQL full-scan
so that DB now does index-scan instead. Also converted use of MAX(column)
to ORDER BY column DESC as MAX() not optimized when MVCC in effect.

Added corresponding INDEX to Blocks on columns (generation, height);

Similar MAX(column) to ORDER BY column DESC improvement for getBlockchainHeight().

Bumped size of HSQLDB TYPE ATTags from VARCHAR(32) to VARCHAR(80)

Improved reflection-based method calls to rethrow underlying exceptions
like DataException, TransformationException, etc. instead of losing
them in general InvocationTargetException.

Re-added atTransaction.toBytes() method so v1 transactions can be verified.

Fixed extraneous additional copy of voter's public key when serializing
in VoteOnPollTransactionTransformer.toBytes()

Fix-up of v1feeder
This commit is contained in:
catbref 2019-03-04 11:41:30 +00:00
parent dbf365472f
commit 752361ecff
12 changed files with 303 additions and 167 deletions

View File

@ -1,5 +1,5 @@
{ {
"coinSupply": "10000000000", "maxBalance": "10000000000",
"blockDifficultyInterval": 10, "blockDifficultyInterval": 10,
"minBlockTime": 60, "minBlockTime": 60,
"maxBlockTime": 300, "maxBlockTime": 300,
@ -7,156 +7,158 @@
"maxBytesPerUnitFee": 1024, "maxBytesPerUnitFee": 1024,
"unitFee": "1.0", "unitFee": "1.0",
"useBrokenMD160ForAddresses": true, "useBrokenMD160ForAddresses": true,
"genesis": { "requireGroupForApproval": false,
"assets": [ "defaultGroupId": 0,
{ "name": "QORA", "description": "QORA coin", "quantity": 10000000000, "isDivisible": true, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC" } "oneNamePerAccount": false,
] "genesisInfo": {
"version": 1,
"timestamp": "1400247274336", "timestamp": "1400247274336",
"generatingBalance": "10000000", "generatingBalance": "10000000",
"transactions": [ "transactions": [
{ "recipient": "QUD9y7NZqTtNwvSAUfewd7zKUGoVivVnTW", "amount": "7032468.191" }, { "type": "ISSUE_ASSET", "owner": "QLpLzqs4DW1FNJByeJ63qaqw3eAYCxfkjR", "assetName": "QORA", "description": "QORA coin", "quantity": 10000000000, "isDivisible": true, "fee": 0, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC" },
{ "recipient": "QVafvKkE5bZTkq8PcXvdaxwuLNN2DGCwYk", "amount": "1716146.084" }, { "type": "GENESIS", "recipient": "QUD9y7NZqTtNwvSAUfewd7zKUGoVivVnTW", "amount": "7032468.191" },
{ "recipient": "QV42QQP7frYWqsVq536g7zSk97fUpf2ZSN", "amount": "5241707.06" }, { "type": "GENESIS", "recipient": "QVafvKkE5bZTkq8PcXvdaxwuLNN2DGCwYk", "amount": "1716146.084" },
{ "recipient": "QgkLTm5GkepJpgr53nAgUyYRsvmyHpb2zT", "amount": "854964.0816" }, { "type": "GENESIS", "recipient": "QV42QQP7frYWqsVq536g7zSk97fUpf2ZSN", "amount": "5241707.06" },
{ "recipient": "Qc8kN338XQULMBuUa6mTqL5tipvELDhzeZ", "amount": "769467.6734" }, { "type": "GENESIS", "recipient": "QgkLTm5GkepJpgr53nAgUyYRsvmyHpb2zT", "amount": "854964.0816" },
{ "recipient": "QQ81BA75jZcpjQBLZE1qcHrXV8ARC1DEec", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "Qc8kN338XQULMBuUa6mTqL5tipvELDhzeZ", "amount": "769467.6734" },
{ "recipient": "QeoSe4DscWX4AFkNBCdm4WS1V7QkUFSQLP", "amount": "854968.3564" }, { "type": "GENESIS", "recipient": "QQ81BA75jZcpjQBLZE1qcHrXV8ARC1DEec", "amount": "85496408.16" },
{ "recipient": "Qdfu3Eh21ZVHNDY1xyNaFqTTEYscSmfSsm", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QeoSe4DscWX4AFkNBCdm4WS1V7QkUFSQLP", "amount": "854968.3564" },
{ "recipient": "QeDSr4abXKRg9j5hTN3TK9UGuH3umThZ42", "amount": "4445813.224" }, { "type": "GENESIS", "recipient": "Qdfu3Eh21ZVHNDY1xyNaFqTTEYscSmfSsm", "amount": "85496408.16" },
{ "recipient": "QQKDuo1txYB9E2xim79YVR6SQ1ZbJtJtFX", "amount": "47023024.49" }, { "type": "GENESIS", "recipient": "QeDSr4abXKRg9j5hTN3TK9UGuH3umThZ42", "amount": "4445813.224" },
{ "recipient": "QLeaeGr4CDA95FmeMtFh8okJRMLoq8Cge5", "amount": "170992816.3" }, { "type": "GENESIS", "recipient": "QQKDuo1txYB9E2xim79YVR6SQ1ZbJtJtFX", "amount": "47023024.49" },
{ "recipient": "QSwN5oa8ZHWJmc6FeAJ8Xr1SHaEuSahw1J", "amount": "3419856.326" }, { "type": "GENESIS", "recipient": "QLeaeGr4CDA95FmeMtFh8okJRMLoq8Cge5", "amount": "170992816.3" },
{ "recipient": "QWnoGd4a7iXqQmNEpUtCb1x7nWgcya8QbE", "amount": "17056533.43" }, { "type": "GENESIS", "recipient": "QSwN5oa8ZHWJmc6FeAJ8Xr1SHaEuSahw1J", "amount": "3419856.326" },
{ "recipient": "QbJqhsJjcy3vkzsJ1kHvgn26pQF3sZEypc", "amount": "42705455.87" }, { "type": "GENESIS", "recipient": "QWnoGd4a7iXqQmNEpUtCb1x7nWgcya8QbE", "amount": "17056533.43" },
{ "recipient": "QiBhBcseKzaDnHKyqEJs8z1Xx2rSb9XhBr", "amount": "141069073.5" }, { "type": "GENESIS", "recipient": "QbJqhsJjcy3vkzsJ1kHvgn26pQF3sZEypc", "amount": "42705455.87" },
{ "recipient": "QTwYwxBhzivFEWY5yfzyz1pqhJ8XCroKwv", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QiBhBcseKzaDnHKyqEJs8z1Xx2rSb9XhBr", "amount": "141069073.5" },
{ "recipient": "QfikxUU15Dy1oxbcDNEcLeU5cHvbrceq3A", "amount": "17099281.63" }, { "type": "GENESIS", "recipient": "QTwYwxBhzivFEWY5yfzyz1pqhJ8XCroKwv", "amount": "85496408.16" },
{ "recipient": "QhdqBmKZeQ3Hg1XUuR5nKtAkw47tuoRi2q", "amount": "12824461.22" }, { "type": "GENESIS", "recipient": "QfikxUU15Dy1oxbcDNEcLeU5cHvbrceq3A", "amount": "17099281.63" },
{ "recipient": "QaVNyTqsTHA6JWMcqntcJf1u9c3qid76xH", "amount": "128244612.2" }, { "type": "GENESIS", "recipient": "QhdqBmKZeQ3Hg1XUuR5nKtAkw47tuoRi2q", "amount": "12824461.22" },
{ "recipient": "QYaDa7bmgo5L9qkcfJKjhPPrQkvGjEoc7y", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QaVNyTqsTHA6JWMcqntcJf1u9c3qid76xH", "amount": "128244612.2" },
{ "recipient": "QQPddvWaYf4pbCyVHEVoyfC72EiaAv4JhT", "amount": "25648922.45" }, { "type": "GENESIS", "recipient": "QYaDa7bmgo5L9qkcfJKjhPPrQkvGjEoc7y", "amount": "85496408.16" },
{ "recipient": "QSQpTNtTZMwaDuNq56Jz73KHWXaey9JrT1", "amount": "26341443.35" }, { "type": "GENESIS", "recipient": "QQPddvWaYf4pbCyVHEVoyfC72EiaAv4JhT", "amount": "25648922.45" },
{ "recipient": "QVjcFWE6TnGePGJEtbNc1thwD2sgHBLvUV", "amount": "42940528.25" }, { "type": "GENESIS", "recipient": "QSQpTNtTZMwaDuNq56Jz73KHWXaey9JrT1", "amount": "26341443.35" },
{ "recipient": "Qga93mWNqTuJYx6o33vjUpFH7Cn4sxLyoG", "amount": "2564892.245" }, { "type": "GENESIS", "recipient": "QVjcFWE6TnGePGJEtbNc1thwD2sgHBLvUV", "amount": "42940528.25" },
{ "recipient": "QXyHKyQPJnb4ejyTkvS26x9sjWnhTTJ1Uc", "amount": "10259568.98" }, { "type": "GENESIS", "recipient": "Qga93mWNqTuJYx6o33vjUpFH7Cn4sxLyoG", "amount": "2564892.245" },
{ "recipient": "QLurSSgJvW7WXHDFSobgfakgqXxjoZzwUH", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QXyHKyQPJnb4ejyTkvS26x9sjWnhTTJ1Uc", "amount": "10259568.98" },
{ "recipient": "QadxfiARcsmwzE93wqq82yXFi3ykM2qdtS", "amount": "79118376.11" }, { "type": "GENESIS", "recipient": "QLurSSgJvW7WXHDFSobgfakgqXxjoZzwUH", "amount": "85496408.16" },
{ "recipient": "QRHhhtz3Cv9RPKB1QBBfkRmRfpXx8vkRa5", "amount": "22435418.54" }, { "type": "GENESIS", "recipient": "QadxfiARcsmwzE93wqq82yXFi3ykM2qdtS", "amount": "79118376.11" },
{ "recipient": "Qh8UnEs55n8jcnBaBwVtrTGkFFFBDyrMqH", "amount": "128757590.7" }, { "type": "GENESIS", "recipient": "QRHhhtz3Cv9RPKB1QBBfkRmRfpXx8vkRa5", "amount": "22435418.54" },
{ "recipient": "QhF7Fu3f54CTYA7zBQ223NQEssi2yAbAcx", "amount": "258481290.8" }, { "type": "GENESIS", "recipient": "Qh8UnEs55n8jcnBaBwVtrTGkFFFBDyrMqH", "amount": "128757590.7" },
{ "recipient": "QPk9VB6tigoifrUYQrw4arBNk7i8HEgsDD", "amount": "128244612.2" }, { "type": "GENESIS", "recipient": "QhF7Fu3f54CTYA7zBQ223NQEssi2yAbAcx", "amount": "258481290.8" },
{ "recipient": "QXWJnEPsdtaLQAEutJFR4ySiMUJCWDzZJX", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QPk9VB6tigoifrUYQrw4arBNk7i8HEgsDD", "amount": "128244612.2" },
{ "recipient": "QVFs42gM4Cixf4Y5vDFvKKxRAamUPMCAVq", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QXWJnEPsdtaLQAEutJFR4ySiMUJCWDzZJX", "amount": "85496408.16" },
{ "recipient": "Qec5ueWc4rcBrty47GZfFSqvLymxvcycFm", "amount": "129091026.7" }, { "type": "GENESIS", "recipient": "QVFs42gM4Cixf4Y5vDFvKKxRAamUPMCAVq", "amount": "85496408.16" },
{ "recipient": "QfYiztbDz1Nb9EMhgHidLycvuPN8HEcHEj", "amount": "128244612.2" }, { "type": "GENESIS", "recipient": "Qec5ueWc4rcBrty47GZfFSqvLymxvcycFm", "amount": "129091026.7" },
{ "recipient": "QPdWsZtaZcAKqk2HWVhEVbws4qG5KUTXmg", "amount": "179285967.9" }, { "type": "GENESIS", "recipient": "QfYiztbDz1Nb9EMhgHidLycvuPN8HEcHEj", "amount": "128244612.2" },
{ "recipient": "QVkNs5NcwQpsrCXpWzuMXkMehJr5mkvLVy", "amount": "8558190.456" }, { "type": "GENESIS", "recipient": "QPdWsZtaZcAKqk2HWVhEVbws4qG5KUTXmg", "amount": "179285967.9" },
{ "recipient": "Qg19DzyEfyZANx6JLy4GrSGF5LuZ2MLqyZ", "amount": "42748204.08" }, { "type": "GENESIS", "recipient": "QVkNs5NcwQpsrCXpWzuMXkMehJr5mkvLVy", "amount": "8558190.456" },
{ "recipient": "Qf3A8L5WJNHt1xZxmayrTp2d5owzdkcxM6", "amount": "50519827.58" }, { "type": "GENESIS", "recipient": "Qg19DzyEfyZANx6JLy4GrSGF5LuZ2MLqyZ", "amount": "42748204.08" },
{ "recipient": "QeKR4W6qkFJGF7Hmu7rSUzTSQiqJzZLXdt", "amount": "10216820.77" }, { "type": "GENESIS", "recipient": "Qf3A8L5WJNHt1xZxmayrTp2d5owzdkcxM6", "amount": "50519827.58" },
{ "recipient": "QWg7T5i3uBY3xeBLFTLYYruR15Ln11vwo4", "amount": "170992816.3" }, { "type": "GENESIS", "recipient": "QeKR4W6qkFJGF7Hmu7rSUzTSQiqJzZLXdt", "amount": "10216820.77" },
{ "recipient": "QUYdM5fHECPZxKQQAmoxoQa2aWg8TZYfPw", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QWg7T5i3uBY3xeBLFTLYYruR15Ln11vwo4", "amount": "170992816.3" },
{ "recipient": "QjhfEZCgrjUbnLRnWqWxzyYqKQpjjxkuA8", "amount": "86665653.61" }, { "type": "GENESIS", "recipient": "QUYdM5fHECPZxKQQAmoxoQa2aWg8TZYfPw", "amount": "85496408.16" },
{ "recipient": "QMA53u3wrzDoxC57CWUJePNdR8FoqinqUS", "amount": "85496408.16" }, { "type": "GENESIS", "recipient": "QjhfEZCgrjUbnLRnWqWxzyYqKQpjjxkuA8", "amount": "86665653.61" },
{ "recipient": "QSuCp6mB5zNNeJKD62aq2hR9h84ks1WhHf", "amount": "161588211.4" }, { "type": "GENESIS", "recipient": "QMA53u3wrzDoxC57CWUJePNdR8FoqinqUS", "amount": "85496408.16" },
{ "recipient": "QS2tCUk7GQefg4zGewwrumxSPmN6fgA7Xc", "amount": "170992816.3" }, { "type": "GENESIS", "recipient": "QSuCp6mB5zNNeJKD62aq2hR9h84ks1WhHf", "amount": "161588211.4" },
{ "recipient": "Qcn6FZRxAgp3japtvjgUkBY6KPfbPZMZtM", "amount": "170992816.3" }, { "type": "GENESIS", "recipient": "QS2tCUk7GQefg4zGewwrumxSPmN6fgA7Xc", "amount": "170992816.3" },
{ "recipient": "QZrmXZkRmjV2GwMt72Rr1ZqHJjv8raDk5J", "amount": "17099281.63" }, { "type": "GENESIS", "recipient": "Qcn6FZRxAgp3japtvjgUkBY6KPfbPZMZtM", "amount": "170992816.3" },
{ "recipient": "QeZzwGDfAHa132jb6r4rQHbgJstLuT8QJ3", "amount": "255875360.3" }, { "type": "GENESIS", "recipient": "QZrmXZkRmjV2GwMt72Rr1ZqHJjv8raDk5J", "amount": "17099281.63" },
{ "recipient": "Qj3L139sMMuFvvjKQDwRnoSgKUnoMhDQs5", "amount": "76946767.34" }, { "type": "GENESIS", "recipient": "QeZzwGDfAHa132jb6r4rQHbgJstLuT8QJ3", "amount": "255875360.3" },
{ "recipient": "QWJvpvbFRZHu7LRbY5MjzvrMBgzJNFYjCX", "amount": "178251461.4" }, { "type": "GENESIS", "recipient": "Qj3L139sMMuFvvjKQDwRnoSgKUnoMhDQs5", "amount": "76946767.34" },
{ "recipient": "QRyECqW54ywKVt4kZTEXyRY17aaFUaxzc4", "amount": "8772355.539" }, { "type": "GENESIS", "recipient": "QWJvpvbFRZHu7LRbY5MjzvrMBgzJNFYjCX", "amount": "178251461.4" },
{ "recipient": "QgpH3K3ArkQTg15xjKqGq3BRgE3aNH9Q2P", "amount": "46766535.26" }, { "type": "GENESIS", "recipient": "QRyECqW54ywKVt4kZTEXyRY17aaFUaxzc4", "amount": "8772355.539" },
{ "recipient": "QVZ6pxi8e3K3S44zLbnrLSLwSoYT8CWbwV", "amount": "233172022.2" }, { "type": "GENESIS", "recipient": "QgpH3K3ArkQTg15xjKqGq3BRgE3aNH9Q2P", "amount": "46766535.26" },
{ "recipient": "QNbA69dbnmwqJHLQeS9v63hSLZXXGkmtC6", "amount": "46626632.05" }, { "type": "GENESIS", "recipient": "QVZ6pxi8e3K3S44zLbnrLSLwSoYT8CWbwV", "amount": "233172022.2" },
{ "recipient": "QgzudSKbcLUeQUhFngotVswDSkbU42dSMr", "amount": "83786479.99" }, { "type": "GENESIS", "recipient": "QNbA69dbnmwqJHLQeS9v63hSLZXXGkmtC6", "amount": "46626632.05" },
{ "recipient": "QfkQ2UzKMBGPwj8Sm31SArjtXoka1ubU3i", "amount": "116345066.7" }, { "type": "GENESIS", "recipient": "QgzudSKbcLUeQUhFngotVswDSkbU42dSMr", "amount": "83786479.99" },
{ "recipient": "QgxHHNwawZeTmQ3i5d9enchi4T9VmzNZ5k", "amount": "155448014.8" }, { "type": "GENESIS", "recipient": "QfkQ2UzKMBGPwj8Sm31SArjtXoka1ubU3i", "amount": "116345066.7" },
{ "recipient": "QMNugJWNsLuV4Qmbzdf8r8RMEdXk5PNM69", "amount": "155448014.8" }, { "type": "GENESIS", "recipient": "QgxHHNwawZeTmQ3i5d9enchi4T9VmzNZ5k", "amount": "155448014.8" },
{ "recipient": "QVhWuJkCjStNMV4U8PtNM9Qz4PvLAEtVSj", "amount": "101041209.6" }, { "type": "GENESIS", "recipient": "QMNugJWNsLuV4Qmbzdf8r8RMEdXk5PNM69", "amount": "155448014.8" },
{ "recipient": "QXjNcckFG9gTr9YbiA3RrRhn3mPJ9zyR4G", "amount": "3108960.297" }, { "type": "GENESIS", "recipient": "QVhWuJkCjStNMV4U8PtNM9Qz4PvLAEtVSj", "amount": "101041209.6" },
{ "recipient": "QThnuBadmExtxk81vhFKimSzbPaPcuPAdm", "amount": "155448014.8" }, { "type": "GENESIS", "recipient": "QXjNcckFG9gTr9YbiA3RrRhn3mPJ9zyR4G", "amount": "3108960.297" },
{ "recipient": "QRc6sQthLHjfkmm2BUhu74g33XtkDoB7JP", "amount": "77773983.95" }, { "type": "GENESIS", "recipient": "QThnuBadmExtxk81vhFKimSzbPaPcuPAdm", "amount": "155448014.8" },
{ "recipient": "QcDLhirHkSbR4TLYeShLzHw61B8UGTFusk", "amount": "23317202.22" }, { "type": "GENESIS", "recipient": "QRc6sQthLHjfkmm2BUhu74g33XtkDoB7JP", "amount": "77773983.95" },
{ "recipient": "QXRnsXE6srHEf2abGh4eogs2mRsmNiuw6V", "amount": "5440680.519" }, { "type": "GENESIS", "recipient": "QcDLhirHkSbR4TLYeShLzHw61B8UGTFusk", "amount": "23317202.22" },
{ "recipient": "QRJmEswbDw4x1kwsLyxtMS9533fv5cDvQV", "amount": "3886200.371" }, { "type": "GENESIS", "recipient": "QXRnsXE6srHEf2abGh4eogs2mRsmNiuw6V", "amount": "5440680.519" },
{ "recipient": "Qg43mCzWmFVwhVfx34g6shXnSU7U7amJNx", "amount": "6217920.593" }, { "type": "GENESIS", "recipient": "QRJmEswbDw4x1kwsLyxtMS9533fv5cDvQV", "amount": "3886200.371" },
{ "recipient": "QQ9PveFTW64yUcXEE6AxhokWCwhmn8F2TD", "amount": "8549640.816" }, { "type": "GENESIS", "recipient": "Qg43mCzWmFVwhVfx34g6shXnSU7U7amJNx", "amount": "6217920.593" },
{ "recipient": "QQaxJuTkW5XXn4DhhRekXpdXaWcsxEfCNG", "amount": "3886200.371" }, { "type": "GENESIS", "recipient": "QQ9PveFTW64yUcXEE6AxhokWCwhmn8F2TD", "amount": "8549640.816" },
{ "recipient": "QifWFqW8XWL5mcNxtdr5z1LVC7XUu9tNSK", "amount": "3116732.697" }, { "type": "GENESIS", "recipient": "QQaxJuTkW5XXn4DhhRekXpdXaWcsxEfCNG", "amount": "3886200.371" },
{ "recipient": "QavhBKRN4vuyzHNNqcWxjcohRAJNTdTmh4", "amount": "154670774.8" }, { "type": "GENESIS", "recipient": "QifWFqW8XWL5mcNxtdr5z1LVC7XUu9tNSK", "amount": "3116732.697" },
{ "recipient": "QMQyR3Hybof8WpQsXPxh19AZFCj4Z4mmke", "amount": "77724007.42" }, { "type": "GENESIS", "recipient": "QavhBKRN4vuyzHNNqcWxjcohRAJNTdTmh4", "amount": "154670774.8" },
{ "recipient": "QbT3GGjp1esTXtowVk2XCtBsKoRB8mkP61", "amount": "77724007.42" }, { "type": "GENESIS", "recipient": "QMQyR3Hybof8WpQsXPxh19AZFCj4Z4mmke", "amount": "77724007.42" },
{ "recipient": "QT13tVMZEtbrgJEsBBcTtnyqGveC7mtqAb", "amount": "23317202.22" }, { "type": "GENESIS", "recipient": "QbT3GGjp1esTXtowVk2XCtBsKoRB8mkP61", "amount": "77724007.42" },
{ "recipient": "QegT2Ws5YjLQzEZ9YMzWsAZMBE8cAygHZN", "amount": "12606834" }, { "type": "GENESIS", "recipient": "QT13tVMZEtbrgJEsBBcTtnyqGveC7mtqAb", "amount": "23317202.22" },
{ "recipient": "QXoKRBJiJGKwvdA3jkmoUhkM7y6vuMp2pn", "amount": "65117173.41" }, { "type": "GENESIS", "recipient": "QegT2Ws5YjLQzEZ9YMzWsAZMBE8cAygHZN", "amount": "12606834" },
{ "recipient": "QY6SpdBzUev9ziqkmyaxESZSbdKwqGdedn", "amount": "89382608.53" }, { "type": "GENESIS", "recipient": "QXoKRBJiJGKwvdA3jkmoUhkM7y6vuMp2pn", "amount": "65117173.41" },
{ "recipient": "QeMxyt1nEE7tbFbioc87xhiKb4szx5DsjY", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QY6SpdBzUev9ziqkmyaxESZSbdKwqGdedn", "amount": "89382608.53" },
{ "recipient": "QcTp3THGZvJ42f2mWsQrawGvgBoSHgHZyk", "amount": "39639243.78" }, { "type": "GENESIS", "recipient": "QeMxyt1nEE7tbFbioc87xhiKb4szx5DsjY", "amount": "15544801.48" },
{ "recipient": "QjSH91mTDN6TeV1naAcfwPhmRogufV4n1u", "amount": "23317202.22" }, { "type": "GENESIS", "recipient": "QcTp3THGZvJ42f2mWsQrawGvgBoSHgHZyk", "amount": "39639243.78" },
{ "recipient": "QiFLELeLm2TFWsnknzje51wMdt3Srkjz8g", "amount": "1554480.148" }, { "type": "GENESIS", "recipient": "QjSH91mTDN6TeV1naAcfwPhmRogufV4n1u", "amount": "23317202.22" },
{ "recipient": "QhxtJ3vvhsvVU9x2j5n2R3TXzutfLMUvBR", "amount": "23317202.22" }, { "type": "GENESIS", "recipient": "QiFLELeLm2TFWsnknzje51wMdt3Srkjz8g", "amount": "1554480.148" },
{ "recipient": "QUtUSNQfqexZZkaZ2s9LcpqjnTezPTnuAx", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QhxtJ3vvhsvVU9x2j5n2R3TXzutfLMUvBR", "amount": "23317202.22" },
{ "recipient": "Qg6sPLxNMYxjEDGLLaFkkWx6ip3py5fLEt", "amount": "777240.0742" }, { "type": "GENESIS", "recipient": "QUtUSNQfqexZZkaZ2s9LcpqjnTezPTnuAx", "amount": "15544801.48" },
{ "recipient": "QeLixskYbdkiAHmhBVMa2Pdi85YPFqw3Ed", "amount": "38862003.71" }, { "type": "GENESIS", "recipient": "Qg6sPLxNMYxjEDGLLaFkkWx6ip3py5fLEt", "amount": "777240.0742" },
{ "recipient": "Qary17o9qvZ2fifiVC8tF5zoBJm79n18zA", "amount": "3893972.772" }, { "type": "GENESIS", "recipient": "QeLixskYbdkiAHmhBVMa2Pdi85YPFqw3Ed", "amount": "38862003.71" },
{ "recipient": "QLvCWDGwzwpR29XgiThMGDX2vxyFW5rFHB", "amount": "8790585.239" }, { "type": "GENESIS", "recipient": "Qary17o9qvZ2fifiVC8tF5zoBJm79n18zA", "amount": "3893972.772" },
{ "recipient": "Qgc77fSoAoUSVJfq62GxxTin6dBtU7Y6Hb", "amount": "194310018.5" }, { "type": "GENESIS", "recipient": "QLvCWDGwzwpR29XgiThMGDX2vxyFW5rFHB", "amount": "8790585.239" },
{ "recipient": "QPmPKjwPLCuRei6abuhMtMocxAEeSuLVcv", "amount": "23317202.22" }, { "type": "GENESIS", "recipient": "Qgc77fSoAoUSVJfq62GxxTin6dBtU7Y6Hb", "amount": "194310018.5" },
{ "recipient": "QcGfZePUN7JHs9WEEkJhXGzALy4JybiS3N", "amount": "194224522.1" }, { "type": "GENESIS", "recipient": "QPmPKjwPLCuRei6abuhMtMocxAEeSuLVcv", "amount": "23317202.22" },
{ "recipient": "QSeXGwk7eQjR8j7bndJST19qWtM2qnqL1u", "amount": "38862003.71" }, { "type": "GENESIS", "recipient": "QcGfZePUN7JHs9WEEkJhXGzALy4JybiS3N", "amount": "194224522.1" },
{ "recipient": "QU9i68h71nKTg4gwc5yJHzNRQdQEswP7Kn", "amount": "139592317.3" }, { "type": "GENESIS", "recipient": "QSeXGwk7eQjR8j7bndJST19qWtM2qnqL1u", "amount": "38862003.71" },
{ "recipient": "QdKrZGCkwXSSeXJhVA1idDXsA4VFtrjPHN", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QU9i68h71nKTg4gwc5yJHzNRQdQEswP7Kn", "amount": "139592317.3" },
{ "recipient": "QiYJ2B797xFpWYFu4XWivhGhyPXLU7S5Mr", "amount": "77724007.42" }, { "type": "GENESIS", "recipient": "QdKrZGCkwXSSeXJhVA1idDXsA4VFtrjPHN", "amount": "15544801.48" },
{ "recipient": "QWxqtsNXUWSjYns2wdngh4WBSWQzLoQHvx", "amount": "232613963.9" }, { "type": "GENESIS", "recipient": "QiYJ2B797xFpWYFu4XWivhGhyPXLU7S5Mr", "amount": "77724007.42" },
{ "recipient": "QTAGfu4FpTZ1bnvnd17YPtB3zabxfWKNeM", "amount": "101041209.6" }, { "type": "GENESIS", "recipient": "QWxqtsNXUWSjYns2wdngh4WBSWQzLoQHvx", "amount": "232613963.9" },
{ "recipient": "QPtRxchgRdwdnoZRwhiAoa77AvVPNSRcQk", "amount": "114254290.9" }, { "type": "GENESIS", "recipient": "QTAGfu4FpTZ1bnvnd17YPtB3zabxfWKNeM", "amount": "101041209.6" },
{ "recipient": "QMcfoVc9Jat2pMFLHcuPEPnY6p6uBK6Dk7", "amount": "77724007.42" }, { "type": "GENESIS", "recipient": "QPtRxchgRdwdnoZRwhiAoa77AvVPNSRcQk", "amount": "114254290.9" },
{ "recipient": "Qi84KosdwSWHZX3qz4WcMgqYGutBmj14dd", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QMcfoVc9Jat2pMFLHcuPEPnY6p6uBK6Dk7", "amount": "77724007.42" },
{ "recipient": "QjAtcHsgig2tvdGr5tR4oGmRarhuojrAK1", "amount": "2883560.675" }, { "type": "GENESIS", "recipient": "Qi84KosdwSWHZX3qz4WcMgqYGutBmj14dd", "amount": "15544801.48" },
{ "recipient": "QPJPNLP2NMHu5athB7ydezdTA6zviCV378", "amount": "6373368.608" }, { "type": "GENESIS", "recipient": "QjAtcHsgig2tvdGr5tR4oGmRarhuojrAK1", "amount": "2883560.675" },
{ "recipient": "QfVLpmLbuUnA1JEe9FmeUAzihoBvqYDp8B", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QPJPNLP2NMHu5athB7ydezdTA6zviCV378", "amount": "6373368.608" },
{ "recipient": "QVVFdy6VLFqAFCb6XSBJLLZybiKgfgDDZV", "amount": "10725913.02" }, { "type": "GENESIS", "recipient": "QfVLpmLbuUnA1JEe9FmeUAzihoBvqYDp8B", "amount": "15544801.48" },
{ "recipient": "QVFXyeG1xpAR8Xg3u7oAmW8unueGAfeaKi", "amount": "31221733.78" }, { "type": "GENESIS", "recipient": "QVVFdy6VLFqAFCb6XSBJLLZybiKgfgDDZV", "amount": "10725913.02" },
{ "recipient": "QdtQtrM1h3TLtwAGCNyoTrW5HyiPRLhrPq", "amount": "138426457.2" }, { "type": "GENESIS", "recipient": "QVFXyeG1xpAR8Xg3u7oAmW8unueGAfeaKi", "amount": "31221733.78" },
{ "recipient": "QMukUMr84Mi2niz6rdhEJMkKJBve7uuRfe", "amount": "116586011.1" }, { "type": "GENESIS", "recipient": "QdtQtrM1h3TLtwAGCNyoTrW5HyiPRLhrPq", "amount": "138426457.2" },
{ "recipient": "QZR8c7dmfwqGPujebFH1miQToJZ4JQfU1X", "amount": "217938116.8" }, { "type": "GENESIS", "recipient": "QMukUMr84Mi2niz6rdhEJMkKJBve7uuRfe", "amount": "116586011.1" },
{ "recipient": "QVV5Uu8eCxufTrBtquDKA96d7Kk8S4V7yX", "amount": "40091961.25" }, { "type": "GENESIS", "recipient": "QZR8c7dmfwqGPujebFH1miQToJZ4JQfU1X", "amount": "217938116.8" },
{ "recipient": "QY9YdgfTEUFvQ2UJszGS63qkwdENkW1PQ5", "amount": "154670774.8" }, { "type": "GENESIS", "recipient": "QVV5Uu8eCxufTrBtquDKA96d7Kk8S4V7yX", "amount": "40091961.25" },
{ "recipient": "QNgiswyhVyNJG4UMzvoSf29wDvGZqqs7WG", "amount": "11658601.11" }, { "type": "GENESIS", "recipient": "QY9YdgfTEUFvQ2UJszGS63qkwdENkW1PQ5", "amount": "154670774.8" },
{ "recipient": "QabjgFiY34oihNkUcy9hpFjQdCaypCShMe", "amount": "54406805.19" }, { "type": "GENESIS", "recipient": "QNgiswyhVyNJG4UMzvoSf29wDvGZqqs7WG", "amount": "11658601.11" },
{ "recipient": "QionidPRekdshCTRL3c7idWWRAqGYcKaFN", "amount": "7772400.742" }, { "type": "GENESIS", "recipient": "QabjgFiY34oihNkUcy9hpFjQdCaypCShMe", "amount": "54406805.19" },
{ "recipient": "QcJdBJiVgiNBNg6ZwZAiEfYDMi5ZTQaYAa", "amount": "81386689.86" }, { "type": "GENESIS", "recipient": "QionidPRekdshCTRL3c7idWWRAqGYcKaFN", "amount": "7772400.742" },
{ "recipient": "QNc8XMpPwM1HESwB7kqw8HoQ5sK2miZ2un", "amount": "190423818.2" }, { "type": "GENESIS", "recipient": "QcJdBJiVgiNBNg6ZwZAiEfYDMi5ZTQaYAa", "amount": "81386689.86" },
{ "recipient": "QUP1SeaNw7CvCnmDp5ai3onWYwThS4GEpu", "amount": "3886200.371" }, { "type": "GENESIS", "recipient": "QNc8XMpPwM1HESwB7kqw8HoQ5sK2miZ2un", "amount": "190423818.2" },
{ "recipient": "QinToqEztNN1TsLdQEuzTHh7vUrEo6JTU2", "amount": "102440241.8" }, { "type": "GENESIS", "recipient": "QUP1SeaNw7CvCnmDp5ai3onWYwThS4GEpu", "amount": "3886200.371" },
{ "recipient": "QcLJYLV4RD4GmPcoNnh7dQrWeYgiiPiqFQ", "amount": "32644083.11" }, { "type": "GENESIS", "recipient": "QinToqEztNN1TsLdQEuzTHh7vUrEo6JTU2", "amount": "102440241.8" },
{ "recipient": "QdYdYGYfgmMX4jQNWMZqLr81R3HdnuiKkv", "amount": "76169527.27" }, { "type": "GENESIS", "recipient": "QcLJYLV4RD4GmPcoNnh7dQrWeYgiiPiqFQ", "amount": "32644083.11" },
{ "recipient": "Qi62mUW5zfJhgRL8FRmCpjSCCnSKtf76S6", "amount": "76169527.27" }, { "type": "GENESIS", "recipient": "QdYdYGYfgmMX4jQNWMZqLr81R3HdnuiKkv", "amount": "76169527.27" },
{ "recipient": "QgFkxqQGkLW6CD95N2zTnT1PPqb9nxWp6b", "amount": "76169527.27" }, { "type": "GENESIS", "recipient": "Qi62mUW5zfJhgRL8FRmCpjSCCnSKtf76S6", "amount": "76169527.27" },
{ "recipient": "QfNUBudYsrrq27YqiHGLUg6BtG52W1W1ci", "amount": "15544801.48" }, { "type": "GENESIS", "recipient": "QgFkxqQGkLW6CD95N2zTnT1PPqb9nxWp6b", "amount": "76169527.27" },
{ "recipient": "QPSFoexnGoMH7EPdg72dM7SvqA7d4M2cu7", "amount": "37307523.56" }, { "type": "GENESIS", "recipient": "QfNUBudYsrrq27YqiHGLUg6BtG52W1W1ci", "amount": "15544801.48" },
{ "recipient": "QQxt5WMvoJ2TNScAzcoxHXPnLTeQ43nQ7N", "amount": "21995894.1" }, { "type": "GENESIS", "recipient": "QPSFoexnGoMH7EPdg72dM7SvqA7d4M2cu7", "amount": "37307523.56" },
{ "recipient": "QicpACxck2oDYpzP8iWRQYD4oirCtvjok9", "amount": "93268808.9" }, { "type": "GENESIS", "recipient": "QQxt5WMvoJ2TNScAzcoxHXPnLTeQ43nQ7N", "amount": "21995894.1" },
{ "recipient": "QVTJkdQkTGgqEED9kAsp4BZbYNJqWfhgGw", "amount": "153909079.5" }, { "type": "GENESIS", "recipient": "QicpACxck2oDYpzP8iWRQYD4oirCtvjok9", "amount": "93268808.9" },
{ "recipient": "QQL5vCkhpXnP9F4wqNiBQsNaCocmRcDSUY", "amount": "15512934.64" }, { "type": "GENESIS", "recipient": "QVTJkdQkTGgqEED9kAsp4BZbYNJqWfhgGw", "amount": "153909079.5" },
{ "recipient": "QSvEex3p2LaZCVBaCyL8MpYsEpHLwed17r", "amount": "155448014.8" }, { "type": "GENESIS", "recipient": "QQL5vCkhpXnP9F4wqNiBQsNaCocmRcDSUY", "amount": "15512934.64" },
{ "recipient": "Qb3Xv96GucQpBG8n96QVFgcs2xXsEWW4CE", "amount": "38862003.71" }, { "type": "GENESIS", "recipient": "QSvEex3p2LaZCVBaCyL8MpYsEpHLwed17r", "amount": "155448014.8" },
{ "recipient": "QdRua9MqXufALpQFDeYiQDYk3EBGdwGXSx", "amount": "230303229.1" }, { "type": "GENESIS", "recipient": "Qb3Xv96GucQpBG8n96QVFgcs2xXsEWW4CE", "amount": "38862003.71" },
{ "recipient": "Qh16Umei91JqiHEVWV8AC6ED9aBqbDYuph", "amount": "231073474" }, { "type": "GENESIS", "recipient": "QdRua9MqXufALpQFDeYiQDYk3EBGdwGXSx", "amount": "230303229.1" },
{ "recipient": "QMu6HXfZCnwaNmyFjjhWTYAUW7k1x7PoVr", "amount": "231073474" }, { "type": "GENESIS", "recipient": "Qh16Umei91JqiHEVWV8AC6ED9aBqbDYuph", "amount": "231073474" },
{ "recipient": "QgcphUTiVHHfHg8e1LVgg5jujVES7ZDUTr", "amount": "115031531" }, { "type": "GENESIS", "recipient": "QMu6HXfZCnwaNmyFjjhWTYAUW7k1x7PoVr", "amount": "231073474" },
{ "recipient": "QbQk9s4j4EAxAguBhmqA8mdtTct3qGnsrx", "amount": "138348733.2" }, { "type": "GENESIS", "recipient": "QgcphUTiVHHfHg8e1LVgg5jujVES7ZDUTr", "amount": "115031531" },
{ "recipient": "QT79PhvBwE6vFzfZ4oh5wdKVsEazZuVJFy", "amount": "6360421.343" } { "type": "GENESIS", "recipient": "QbQk9s4j4EAxAguBhmqA8mdtTct3qGnsrx", "amount": "138348733.2" },
{ "type": "GENESIS", "recipient": "QT79PhvBwE6vFzfZ4oh5wdKVsEazZuVJFy", "amount": "6360421.343" }
] ]
}, },
"featureTriggers": { "featureTriggers": {
"message": { "height": "99000" }, "messageHeight": 99000,
"AT": { "height": "99000" }, "atHeight": 99000,
"assets": { "timestamp": "0" }, "assetsTimestamp": 0,
"voting": { "timestamp": "1403715600000" }, "votingTimestamp": "1403715600000",
"arbitrary": { "timestamp": "1405702800000" }, "arbitraryTimestamp": "1405702800000",
"powfix": { "timestamp": "1456426800000" }, "powfixTimestamp": "1456426800000",
"v2" : { "timestamp": "1552500000000" } "v2Timestamp": "1552500000000"
} }
} }

View File

@ -3,6 +3,7 @@ package org.qora.block;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -85,7 +86,7 @@ public class GenesisBlock extends Block {
info.timestamp = System.currentTimeMillis(); info.timestamp = System.currentTimeMillis();
} }
transactionsData = Arrays.asList(info.transactions); transactionsData = new ArrayList<TransactionData>(Arrays.asList(info.transactions));
// Add default values to transactions // Add default values to transactions
transactionsData.stream().forEach(transactionData -> { transactionsData.stream().forEach(transactionData -> {
@ -112,7 +113,7 @@ public class GenesisBlock extends Block {
} }
// Convert ISSUE_ASSET transactions into initial assets // Convert ISSUE_ASSET transactions into initial assets
issueAssetTransactions.stream().map(transactionData -> { initialAssets = issueAssetTransactions.stream().map(transactionData -> {
IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData; IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData;
return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(), return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(),

View File

@ -168,6 +168,10 @@ public abstract class TransactionData {
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
// Comparing exact same object
if (this == other)
return true;
// If we don't have a signature then fail // If we don't have a signature then fail
if (this.signature == null) if (this.signature == null)
return false; return false;

View File

@ -213,7 +213,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
@Override @Override
public List<OrderData> getAggregatedOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset, Boolean reverse) throws DataException { public List<OrderData> getAggregatedOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT price, sum(amount - fulfilled), max(ordered) FROM AssetOrders " String sql = "SELECT price, SUM(amount - fulfilled), MAX(ordered) FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND is_closed = FALSE AND is_fulfilled = FALSE GROUP BY price ORDER BY price"; + "WHERE have_asset_id = ? AND want_asset_id = ? AND is_closed = FALSE AND is_fulfilled = FALSE GROUP BY price ORDER BY price";
if (reverse != null && reverse) if (reverse != null && reverse)
sql += " DESC"; sql += " DESC";

View File

@ -3,9 +3,7 @@ package org.qora.repository.hsqldb;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import org.qora.data.block.BlockData; import org.qora.data.block.BlockData;
@ -15,6 +13,9 @@ import org.qora.repository.BlockRepository;
import org.qora.repository.DataException; import org.qora.repository.DataException;
import org.qora.repository.TransactionRepository; import org.qora.repository.TransactionRepository;
import static org.qora.repository.hsqldb.HSQLDBRepository.toOffsetDateTime;
import static org.qora.repository.hsqldb.HSQLDBRepository.getZonedTimestampMilli;
public class HSQLDBBlockRepository implements BlockRepository { public class HSQLDBBlockRepository implements BlockRepository {
private static final String BLOCK_DB_COLUMNS = "version, reference, transaction_count, total_fees, " private static final String BLOCK_DB_COLUMNS = "version, reference, transaction_count, total_fees, "
@ -37,7 +38,7 @@ public class HSQLDBBlockRepository implements BlockRepository {
BigDecimal totalFees = resultSet.getBigDecimal(4); BigDecimal totalFees = resultSet.getBigDecimal(4);
byte[] transactionsSignature = resultSet.getBytes(5); byte[] transactionsSignature = resultSet.getBytes(5);
int height = resultSet.getInt(6); int height = resultSet.getInt(6);
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime(); long timestamp = getZonedTimestampMilli(resultSet, 7);
BigDecimal generatingBalance = resultSet.getBigDecimal(8); BigDecimal generatingBalance = resultSet.getBigDecimal(8);
byte[] generatorPublicKey = resultSet.getBytes(9); byte[] generatorPublicKey = resultSet.getBytes(9);
byte[] generatorSignature = resultSet.getBytes(10); byte[] generatorSignature = resultSet.getBytes(10);
@ -92,7 +93,9 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override @Override
public int getHeightFromTimestamp(long timestamp) throws DataException { public int getHeightFromTimestamp(long timestamp) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT MAX(height) FROM Blocks WHERE generation <= ?", new Timestamp(timestamp))) { // Uses (generation, height) index
try (ResultSet resultSet = this.repository.checkedExecute("SELECT height FROM Blocks WHERE generation <= ? ORDER BY generation DESC LIMIT 1",
toOffsetDateTime(timestamp))) {
if (resultSet == null) if (resultSet == null)
return 0; return 0;
@ -104,7 +107,7 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override @Override
public int getBlockchainHeight() throws DataException { public int getBlockchainHeight() throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT MAX(height) FROM Blocks LIMIT 1")) { try (ResultSet resultSet = this.repository.checkedExecute("SELECT height FROM Blocks ORDER BY height DESC LIMIT 1")) {
if (resultSet == null) if (resultSet == null)
return 0; return 0;
@ -153,7 +156,7 @@ public class HSQLDBBlockRepository implements BlockRepository {
saveHelper.bind("signature", blockData.getSignature()).bind("version", blockData.getVersion()).bind("reference", blockData.getReference()) saveHelper.bind("signature", blockData.getSignature()).bind("version", blockData.getVersion()).bind("reference", blockData.getReference())
.bind("transaction_count", blockData.getTransactionCount()).bind("total_fees", blockData.getTotalFees()) .bind("transaction_count", blockData.getTransactionCount()).bind("total_fees", blockData.getTotalFees())
.bind("transactions_signature", blockData.getTransactionsSignature()).bind("height", blockData.getHeight()) .bind("transactions_signature", blockData.getTransactionsSignature()).bind("height", blockData.getHeight())
.bind("generation", new Timestamp(blockData.getTimestamp())).bind("generating_balance", blockData.getGeneratingBalance()) .bind("generation", toOffsetDateTime(blockData.getTimestamp())).bind("generating_balance", blockData.getGeneratingBalance())
.bind("generator", blockData.getGeneratorPublicKey()).bind("generator_signature", blockData.getGeneratorSignature()) .bind("generator", blockData.getGeneratorPublicKey()).bind("generator_signature", blockData.getGeneratorSignature())
.bind("AT_count", blockData.getATCount()).bind("AT_fees", blockData.getATFees()); .bind("AT_count", blockData.getATCount()).bind("AT_fees", blockData.getATFees());

View File

@ -109,7 +109,7 @@ public class HSQLDBDatabaseUpdates {
stmt.execute("CREATE TYPE AssetOrderID AS VARBINARY(64)"); stmt.execute("CREATE TYPE AssetOrderID AS VARBINARY(64)");
stmt.execute("CREATE TYPE ATName AS VARCHAR(32) COLLATE SQL_TEXT_UCC_NO_PAD"); stmt.execute("CREATE TYPE ATName AS VARCHAR(32) COLLATE SQL_TEXT_UCC_NO_PAD");
stmt.execute("CREATE TYPE ATType AS VARCHAR(32) COLLATE SQL_TEXT_UCC_NO_PAD"); stmt.execute("CREATE TYPE ATType AS VARCHAR(32) COLLATE SQL_TEXT_UCC_NO_PAD");
stmt.execute("CREATE TYPE ATTags AS VARCHAR(32) COLLATE SQL_TEXT_UCC_NO_PAD"); stmt.execute("CREATE TYPE ATTags AS VARCHAR(80) COLLATE SQL_TEXT_UCC_NO_PAD");
stmt.execute("CREATE TYPE ATCode AS BLOB(64K)"); // 16bit * 1 stmt.execute("CREATE TYPE ATCode AS BLOB(64K)"); // 16bit * 1
stmt.execute("CREATE TYPE ATState AS BLOB(1M)"); // 16bit * 8 + 16bit * 4 + 16bit * 4 stmt.execute("CREATE TYPE ATState AS BLOB(1M)"); // 16bit * 8 + 16bit * 4 + 16bit * 4
stmt.execute("CREATE TYPE ATCreationBytes AS BLOB(576K)"); // 16bit * 1 + 16bit * 8 stmt.execute("CREATE TYPE ATCreationBytes AS BLOB(576K)"); // 16bit * 1 + 16bit * 8
@ -133,6 +133,8 @@ public class HSQLDBDatabaseUpdates {
stmt.execute("CREATE INDEX BlockGeneratorIndex ON Blocks (generator)"); stmt.execute("CREATE INDEX BlockGeneratorIndex ON Blocks (generator)");
// For finding blocks by reference, e.g. child blocks. // For finding blocks by reference, e.g. child blocks.
stmt.execute("CREATE INDEX BlockReferenceIndex ON Blocks (reference)"); stmt.execute("CREATE INDEX BlockReferenceIndex ON Blocks (reference)");
// For finding blocks by generation timestamp or finding height of latest block immediately before generation timestamp, etc.
stmt.execute("CREATE INDEX BlockGenerationHeightIndex ON Blocks (generation, height)");
// Use a separate table space as this table will be very large. // Use a separate table space as this table will be very large.
stmt.execute("SET TABLE Blocks NEW SPACE"); stmt.execute("SET TABLE Blocks NEW SPACE");
break; break;
@ -583,6 +585,11 @@ public class HSQLDBDatabaseUpdates {
stmt.execute("ALTER TABLE Groups ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0"); stmt.execute("ALTER TABLE Groups ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
break; break;
case 37:
// Performance-improving INDEX
stmt.execute("CREATE INDEX IF NOT EXISTS BlockGenerationHeightIndex ON Blocks (generation, height)");
break;
default: default:
// nothing to do // nothing to do
return false; return false;

View File

@ -7,6 +7,9 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.TimeZone; import java.util.TimeZone;
@ -385,4 +388,23 @@ public class HSQLDBRepository implements Repository {
return e; return e;
} }
/** Converts milliseconds from epoch to OffsetDateTime needed for TIMESTAMP WITH TIME ZONE columns. */
/* package */ static OffsetDateTime toOffsetDateTime(long timestamp) {
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
}
/** Converts OffsetDateTime from TIMESTAMP WITH TIME ZONE column to milliseconds from epoch. */
/* package */ static long fromOffsetDateTime(OffsetDateTime offsetDateTime) {
return offsetDateTime.toInstant().toEpochMilli();
}
/** Returns TIMESTAMP WITH TIME ZONE column value as milliseconds from epoch, or null. */
/* package */ static Long getZonedTimestampMilli(ResultSet resultSet, int columnIndex) throws SQLException {
OffsetDateTime offsetDateTime = resultSet.getObject(columnIndex, OffsetDateTime.class);
if (offsetDateTime == null)
return null;
return offsetDateTime.toInstant().toEpochMilli();
}
} }

View File

@ -187,7 +187,12 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
try { try {
// params: long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature // params: long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature
return (TransactionData) subclassInfos[type.value].fromBaseMethod.invoke(txRepository, timestamp, txGroupId, reference, creatorPublicKey, fee, signature); return (TransactionData) subclassInfos[type.value].fromBaseMethod.invoke(txRepository, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof DataException)
throw (DataException) e.getCause();
throw new DataException("Unsupported transaction type [" + type.name() + "] during fetch from HSQLDB repository");
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new DataException("Unsupported transaction type [" + type.name() + "] during fetch from HSQLDB repository"); throw new DataException("Unsupported transaction type [" + type.name() + "] during fetch from HSQLDB repository");
} }
} }
@ -699,7 +704,12 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
try { try {
subclassInfos[type.value].saveMethod.invoke(txRepository, transactionData); subclassInfos[type.value].saveMethod.invoke(txRepository, transactionData);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof DataException)
throw (DataException) e.getCause();
throw new DataException("Exception during save of transaction type [" + type.name() + "] into HSQLDB repository");
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new DataException("Unsupported transaction type [" + type.name() + "] during save into HSQLDB repository"); throw new DataException("Unsupported transaction type [" + type.name() + "] during save into HSQLDB repository");
} }
} }

View File

@ -1,12 +1,28 @@
package org.qora.transform.transaction; package org.qora.transform.transaction;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.qora.data.transaction.ATTransactionData;
import org.qora.data.transaction.TransactionData; import org.qora.data.transaction.TransactionData;
import org.qora.transform.TransformationException; import org.qora.transform.TransformationException;
import org.qora.utils.Serialization;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
public class AtTransactionTransformer extends TransactionTransformer { public class AtTransactionTransformer extends TransactionTransformer {
private static final int SENDER_LENGTH = ADDRESS_LENGTH;
private static final int RECIPIENT_LENGTH = ADDRESS_LENGTH;
private static final int AMOUNT_LENGTH = BIG_DECIMAL_LENGTH;
private static final int ASSET_ID_LENGTH = LONG_LENGTH;
private static final int DATA_SIZE_LENGTH = INT_LENGTH;
private static final int EXTRAS_LENGTH = SENDER_LENGTH + RECIPIENT_LENGTH + AMOUNT_LENGTH + ASSET_ID_LENGTH + DATA_SIZE_LENGTH;
protected static final TransactionLayout layout = null; protected static final TransactionLayout layout = null;
// Property lengths // Property lengths
@ -15,12 +31,48 @@ public class AtTransactionTransformer extends TransactionTransformer {
} }
public static int getDataLength(TransactionData transactionData) throws TransformationException { public static int getDataLength(TransactionData transactionData) throws TransformationException {
// AT Transactions aren't serialized so don't take up any space in the block. ATTransactionData atTransactionData = (ATTransactionData) transactionData;
return 0;
return getBaseLength(transactionData) + EXTRAS_LENGTH + atTransactionData.getMessage().length;
} }
public static byte[] toBytes(TransactionData transactionData) throws TransformationException { public static byte[] toBytes(TransactionData transactionData) throws TransformationException {
throw new TransformationException("Serialized AT Transactions should not exist!"); try {
ATTransactionData atTransactionData = (ATTransactionData) transactionData;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bytes.write(Ints.toByteArray(atTransactionData.getType().value));
bytes.write(Longs.toByteArray(atTransactionData.getTimestamp()));
bytes.write(atTransactionData.getReference());
Serialization.serializeAddress(bytes, atTransactionData.getATAddress());
Serialization.serializeAddress(bytes, atTransactionData.getRecipient());
// Only emit amount if greater than zero (safer than checking assetId)
if (atTransactionData.getAmount().compareTo(BigDecimal.ZERO) > 0) {
Serialization.serializeBigDecimal(bytes, atTransactionData.getAmount());
bytes.write(Longs.toByteArray(atTransactionData.getAssetId()));
}
byte[] message = atTransactionData.getMessage();
if (message.length > 0) {
bytes.write(Ints.toByteArray(message.length));
bytes.write(message);
} else {
bytes.write(Ints.toByteArray(0));
}
Serialization.serializeBigDecimal(bytes, atTransactionData.getFee());
if (atTransactionData.getSignature() != null)
bytes.write(atTransactionData.getSignature());
return bytes.toByteArray();
} catch (IOException | ClassCastException e) {
throw new TransformationException(e);
}
} }
} }

View File

@ -210,7 +210,15 @@ public abstract class TransactionTransformer extends Transformer {
return (TransactionData) method.invoke(null, byteBuffer); return (TransactionData) method.invoke(null, byteBuffer);
} catch (BufferUnderflowException e) { } catch (BufferUnderflowException e) {
throw new TransformationException("Byte data too short for transaction type [" + type.value + "]"); throw new TransformationException("Byte data too short for transaction type [" + type.value + "]");
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof BufferUnderflowException)
throw (BufferUnderflowException) e.getCause();
if (e.getCause() instanceof TransformationException)
throw (TransformationException) e.getCause();
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion from bytes");
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion from bytes"); throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion from bytes");
} }
} }
@ -231,7 +239,12 @@ public abstract class TransactionTransformer extends Transformer {
try { try {
Method method = subclassInfos[type.value].getDataLengthMethod; Method method = subclassInfos[type.value].getDataLengthMethod;
return (int) method.invoke(null, transactionData); return (int) method.invoke(null, transactionData);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof TransformationException)
throw (TransformationException) e.getCause();
throw new TransformationException("Internal error with transaction type [" + type.value + "] when requesting byte length");
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new TransformationException("Internal error with transaction type [" + type.value + "] when requesting byte length"); throw new TransformationException("Internal error with transaction type [" + type.value + "] when requesting byte length");
} }
} }
@ -242,7 +255,12 @@ public abstract class TransactionTransformer extends Transformer {
try { try {
Method method = subclassInfos[type.value].toBytesMethod; Method method = subclassInfos[type.value].toBytesMethod;
return (byte[]) method.invoke(null, transactionData); return (byte[]) method.invoke(null, transactionData);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof TransformationException)
throw (TransformationException) e.getCause();
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes");
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes"); throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes");
} }
} }
@ -262,7 +280,12 @@ public abstract class TransactionTransformer extends Transformer {
try { try {
Method method = subclassInfos[type.value].toBytesForSigningImplMethod; Method method = subclassInfos[type.value].toBytesForSigningImplMethod;
return (byte[]) method.invoke(null, transactionData); return (byte[]) method.invoke(null, transactionData);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof TransformationException)
throw (TransformationException) e.getCause();
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes for signing");
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes for signing"); throw new TransformationException("Internal error with transaction type [" + type.value + "] during conversion to bytes for signing");
} }
} }

View File

@ -80,8 +80,6 @@ public class VoteOnPollTransactionTransformer extends TransactionTransformer {
transformCommonBytes(transactionData, bytes); transformCommonBytes(transactionData, bytes);
bytes.write(voteOnPollTransactionData.getVoterPublicKey());
Serialization.serializeSizedString(bytes, voteOnPollTransactionData.getPollName()); Serialization.serializeSizedString(bytes, voteOnPollTransactionData.getPollName());
bytes.write(Ints.toByteArray(voteOnPollTransactionData.getOptionIndex())); bytes.write(Ints.toByteArray(voteOnPollTransactionData.getOptionIndex()));

View File

@ -15,6 +15,7 @@ import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.Security;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -23,6 +24,8 @@ import java.util.Map;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.JSONValue; import org.json.simple.JSONValue;
@ -44,6 +47,7 @@ import org.qora.repository.Repository;
import org.qora.repository.RepositoryFactory; import org.qora.repository.RepositoryFactory;
import org.qora.repository.RepositoryManager; import org.qora.repository.RepositoryManager;
import org.qora.repository.hsqldb.HSQLDBRepositoryFactory; import org.qora.repository.hsqldb.HSQLDBRepositoryFactory;
import org.qora.settings.Settings;
import org.qora.transform.TransformationException; import org.qora.transform.TransformationException;
import org.qora.transform.block.BlockTransformer; import org.qora.transform.block.BlockTransformer;
import org.qora.transform.transaction.AtTransactionTransformer; import org.qora.transform.transaction.AtTransactionTransformer;
@ -57,6 +61,11 @@ import com.google.common.primitives.Ints;
public class v1feeder extends Thread { public class v1feeder extends Thread {
static {
// This must go before any calls to LogManager/Logger
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
}
private static final Logger LOGGER = LogManager.getLogger(v1feeder.class); private static final Logger LOGGER = LogManager.getLogger(v1feeder.class);
private static final int INACTIVITY_TIMEOUT = 60 * 1000; // milliseconds private static final int INACTIVITY_TIMEOUT = 60 * 1000; // milliseconds
@ -529,6 +538,11 @@ public class v1feeder extends Thread {
String legacyATPathname = args[0]; String legacyATPathname = args[0];
readLegacyATs(legacyATPathname); readLegacyATs(legacyATPathname);
Security.insertProviderAt(new BouncyCastleProvider(), 0);
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
Settings.getInstance();
try { try {
RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(Controller.connectionUrl); RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(Controller.connectionUrl);
RepositoryManager.setRepositoryFactory(repositoryFactory); RepositoryManager.setRepositoryFactory(repositoryFactory);