From 752361ecff4c096f46f14aa013b0e5551b5b4034 Mon Sep 17 00:00:00 2001 From: catbref Date: Mon, 4 Mar 2019 11:41:30 +0000 Subject: [PATCH] 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 --- blockchain.json | 294 +++++++++--------- .../java/org/qora/block/GenesisBlock.java | 5 +- .../data/transaction/TransactionData.java | 4 + .../hsqldb/HSQLDBAssetRepository.java | 2 +- .../hsqldb/HSQLDBBlockRepository.java | 15 +- .../hsqldb/HSQLDBDatabaseUpdates.java | 9 +- .../repository/hsqldb/HSQLDBRepository.java | 22 ++ .../HSQLDBTransactionRepository.java | 14 +- .../transaction/AtTransactionTransformer.java | 58 +++- .../transaction/TransactionTransformer.java | 31 +- .../VoteOnPollTransactionTransformer.java | 2 - src/main/java/org/qora/v1feeder.java | 14 + 12 files changed, 303 insertions(+), 167 deletions(-) diff --git a/blockchain.json b/blockchain.json index 83563980..477d6f21 100644 --- a/blockchain.json +++ b/blockchain.json @@ -1,5 +1,5 @@ { - "coinSupply": "10000000000", + "maxBalance": "10000000000", "blockDifficultyInterval": 10, "minBlockTime": 60, "maxBlockTime": 300, @@ -7,156 +7,158 @@ "maxBytesPerUnitFee": 1024, "unitFee": "1.0", "useBrokenMD160ForAddresses": true, - "genesis": { - "assets": [ - { "name": "QORA", "description": "QORA coin", "quantity": 10000000000, "isDivisible": true, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC" } - ] + "requireGroupForApproval": false, + "defaultGroupId": 0, + "oneNamePerAccount": false, + "genesisInfo": { + "version": 1, "timestamp": "1400247274336", "generatingBalance": "10000000", "transactions": [ - { "recipient": "QUD9y7NZqTtNwvSAUfewd7zKUGoVivVnTW", "amount": "7032468.191" }, - { "recipient": "QVafvKkE5bZTkq8PcXvdaxwuLNN2DGCwYk", "amount": "1716146.084" }, - { "recipient": "QV42QQP7frYWqsVq536g7zSk97fUpf2ZSN", "amount": "5241707.06" }, - { "recipient": "QgkLTm5GkepJpgr53nAgUyYRsvmyHpb2zT", "amount": "854964.0816" }, - { "recipient": "Qc8kN338XQULMBuUa6mTqL5tipvELDhzeZ", "amount": "769467.6734" }, - { "recipient": "QQ81BA75jZcpjQBLZE1qcHrXV8ARC1DEec", "amount": "85496408.16" }, - { "recipient": "QeoSe4DscWX4AFkNBCdm4WS1V7QkUFSQLP", "amount": "854968.3564" }, - { "recipient": "Qdfu3Eh21ZVHNDY1xyNaFqTTEYscSmfSsm", "amount": "85496408.16" }, - { "recipient": "QeDSr4abXKRg9j5hTN3TK9UGuH3umThZ42", "amount": "4445813.224" }, - { "recipient": "QQKDuo1txYB9E2xim79YVR6SQ1ZbJtJtFX", "amount": "47023024.49" }, - { "recipient": "QLeaeGr4CDA95FmeMtFh8okJRMLoq8Cge5", "amount": "170992816.3" }, - { "recipient": "QSwN5oa8ZHWJmc6FeAJ8Xr1SHaEuSahw1J", "amount": "3419856.326" }, - { "recipient": "QWnoGd4a7iXqQmNEpUtCb1x7nWgcya8QbE", "amount": "17056533.43" }, - { "recipient": "QbJqhsJjcy3vkzsJ1kHvgn26pQF3sZEypc", "amount": "42705455.87" }, - { "recipient": "QiBhBcseKzaDnHKyqEJs8z1Xx2rSb9XhBr", "amount": "141069073.5" }, - { "recipient": "QTwYwxBhzivFEWY5yfzyz1pqhJ8XCroKwv", "amount": "85496408.16" }, - { "recipient": "QfikxUU15Dy1oxbcDNEcLeU5cHvbrceq3A", "amount": "17099281.63" }, - { "recipient": "QhdqBmKZeQ3Hg1XUuR5nKtAkw47tuoRi2q", "amount": "12824461.22" }, - { "recipient": "QaVNyTqsTHA6JWMcqntcJf1u9c3qid76xH", "amount": "128244612.2" }, - { "recipient": "QYaDa7bmgo5L9qkcfJKjhPPrQkvGjEoc7y", "amount": "85496408.16" }, - { "recipient": "QQPddvWaYf4pbCyVHEVoyfC72EiaAv4JhT", "amount": "25648922.45" }, - { "recipient": "QSQpTNtTZMwaDuNq56Jz73KHWXaey9JrT1", "amount": "26341443.35" }, - { "recipient": "QVjcFWE6TnGePGJEtbNc1thwD2sgHBLvUV", "amount": "42940528.25" }, - { "recipient": "Qga93mWNqTuJYx6o33vjUpFH7Cn4sxLyoG", "amount": "2564892.245" }, - { "recipient": "QXyHKyQPJnb4ejyTkvS26x9sjWnhTTJ1Uc", "amount": "10259568.98" }, - { "recipient": "QLurSSgJvW7WXHDFSobgfakgqXxjoZzwUH", "amount": "85496408.16" }, - { "recipient": "QadxfiARcsmwzE93wqq82yXFi3ykM2qdtS", "amount": "79118376.11" }, - { "recipient": "QRHhhtz3Cv9RPKB1QBBfkRmRfpXx8vkRa5", "amount": "22435418.54" }, - { "recipient": "Qh8UnEs55n8jcnBaBwVtrTGkFFFBDyrMqH", "amount": "128757590.7" }, - { "recipient": "QhF7Fu3f54CTYA7zBQ223NQEssi2yAbAcx", "amount": "258481290.8" }, - { "recipient": "QPk9VB6tigoifrUYQrw4arBNk7i8HEgsDD", "amount": "128244612.2" }, - { "recipient": "QXWJnEPsdtaLQAEutJFR4ySiMUJCWDzZJX", "amount": "85496408.16" }, - { "recipient": "QVFs42gM4Cixf4Y5vDFvKKxRAamUPMCAVq", "amount": "85496408.16" }, - { "recipient": "Qec5ueWc4rcBrty47GZfFSqvLymxvcycFm", "amount": "129091026.7" }, - { "recipient": "QfYiztbDz1Nb9EMhgHidLycvuPN8HEcHEj", "amount": "128244612.2" }, - { "recipient": "QPdWsZtaZcAKqk2HWVhEVbws4qG5KUTXmg", "amount": "179285967.9" }, - { "recipient": "QVkNs5NcwQpsrCXpWzuMXkMehJr5mkvLVy", "amount": "8558190.456" }, - { "recipient": "Qg19DzyEfyZANx6JLy4GrSGF5LuZ2MLqyZ", "amount": "42748204.08" }, - { "recipient": "Qf3A8L5WJNHt1xZxmayrTp2d5owzdkcxM6", "amount": "50519827.58" }, - { "recipient": "QeKR4W6qkFJGF7Hmu7rSUzTSQiqJzZLXdt", "amount": "10216820.77" }, - { "recipient": "QWg7T5i3uBY3xeBLFTLYYruR15Ln11vwo4", "amount": "170992816.3" }, - { "recipient": "QUYdM5fHECPZxKQQAmoxoQa2aWg8TZYfPw", "amount": "85496408.16" }, - { "recipient": "QjhfEZCgrjUbnLRnWqWxzyYqKQpjjxkuA8", "amount": "86665653.61" }, - { "recipient": "QMA53u3wrzDoxC57CWUJePNdR8FoqinqUS", "amount": "85496408.16" }, - { "recipient": "QSuCp6mB5zNNeJKD62aq2hR9h84ks1WhHf", "amount": "161588211.4" }, - { "recipient": "QS2tCUk7GQefg4zGewwrumxSPmN6fgA7Xc", "amount": "170992816.3" }, - { "recipient": "Qcn6FZRxAgp3japtvjgUkBY6KPfbPZMZtM", "amount": "170992816.3" }, - { "recipient": "QZrmXZkRmjV2GwMt72Rr1ZqHJjv8raDk5J", "amount": "17099281.63" }, - { "recipient": "QeZzwGDfAHa132jb6r4rQHbgJstLuT8QJ3", "amount": "255875360.3" }, - { "recipient": "Qj3L139sMMuFvvjKQDwRnoSgKUnoMhDQs5", "amount": "76946767.34" }, - { "recipient": "QWJvpvbFRZHu7LRbY5MjzvrMBgzJNFYjCX", "amount": "178251461.4" }, - { "recipient": "QRyECqW54ywKVt4kZTEXyRY17aaFUaxzc4", "amount": "8772355.539" }, - { "recipient": "QgpH3K3ArkQTg15xjKqGq3BRgE3aNH9Q2P", "amount": "46766535.26" }, - { "recipient": "QVZ6pxi8e3K3S44zLbnrLSLwSoYT8CWbwV", "amount": "233172022.2" }, - { "recipient": "QNbA69dbnmwqJHLQeS9v63hSLZXXGkmtC6", "amount": "46626632.05" }, - { "recipient": "QgzudSKbcLUeQUhFngotVswDSkbU42dSMr", "amount": "83786479.99" }, - { "recipient": "QfkQ2UzKMBGPwj8Sm31SArjtXoka1ubU3i", "amount": "116345066.7" }, - { "recipient": "QgxHHNwawZeTmQ3i5d9enchi4T9VmzNZ5k", "amount": "155448014.8" }, - { "recipient": "QMNugJWNsLuV4Qmbzdf8r8RMEdXk5PNM69", "amount": "155448014.8" }, - { "recipient": "QVhWuJkCjStNMV4U8PtNM9Qz4PvLAEtVSj", "amount": "101041209.6" }, - { "recipient": "QXjNcckFG9gTr9YbiA3RrRhn3mPJ9zyR4G", "amount": "3108960.297" }, - { "recipient": "QThnuBadmExtxk81vhFKimSzbPaPcuPAdm", "amount": "155448014.8" }, - { "recipient": "QRc6sQthLHjfkmm2BUhu74g33XtkDoB7JP", "amount": "77773983.95" }, - { "recipient": "QcDLhirHkSbR4TLYeShLzHw61B8UGTFusk", "amount": "23317202.22" }, - { "recipient": "QXRnsXE6srHEf2abGh4eogs2mRsmNiuw6V", "amount": "5440680.519" }, - { "recipient": "QRJmEswbDw4x1kwsLyxtMS9533fv5cDvQV", "amount": "3886200.371" }, - { "recipient": "Qg43mCzWmFVwhVfx34g6shXnSU7U7amJNx", "amount": "6217920.593" }, - { "recipient": "QQ9PveFTW64yUcXEE6AxhokWCwhmn8F2TD", "amount": "8549640.816" }, - { "recipient": "QQaxJuTkW5XXn4DhhRekXpdXaWcsxEfCNG", "amount": "3886200.371" }, - { "recipient": "QifWFqW8XWL5mcNxtdr5z1LVC7XUu9tNSK", "amount": "3116732.697" }, - { "recipient": "QavhBKRN4vuyzHNNqcWxjcohRAJNTdTmh4", "amount": "154670774.8" }, - { "recipient": "QMQyR3Hybof8WpQsXPxh19AZFCj4Z4mmke", "amount": "77724007.42" }, - { "recipient": "QbT3GGjp1esTXtowVk2XCtBsKoRB8mkP61", "amount": "77724007.42" }, - { "recipient": "QT13tVMZEtbrgJEsBBcTtnyqGveC7mtqAb", "amount": "23317202.22" }, - { "recipient": "QegT2Ws5YjLQzEZ9YMzWsAZMBE8cAygHZN", "amount": "12606834" }, - { "recipient": "QXoKRBJiJGKwvdA3jkmoUhkM7y6vuMp2pn", "amount": "65117173.41" }, - { "recipient": "QY6SpdBzUev9ziqkmyaxESZSbdKwqGdedn", "amount": "89382608.53" }, - { "recipient": "QeMxyt1nEE7tbFbioc87xhiKb4szx5DsjY", "amount": "15544801.48" }, - { "recipient": "QcTp3THGZvJ42f2mWsQrawGvgBoSHgHZyk", "amount": "39639243.78" }, - { "recipient": "QjSH91mTDN6TeV1naAcfwPhmRogufV4n1u", "amount": "23317202.22" }, - { "recipient": "QiFLELeLm2TFWsnknzje51wMdt3Srkjz8g", "amount": "1554480.148" }, - { "recipient": "QhxtJ3vvhsvVU9x2j5n2R3TXzutfLMUvBR", "amount": "23317202.22" }, - { "recipient": "QUtUSNQfqexZZkaZ2s9LcpqjnTezPTnuAx", "amount": "15544801.48" }, - { "recipient": "Qg6sPLxNMYxjEDGLLaFkkWx6ip3py5fLEt", "amount": "777240.0742" }, - { "recipient": "QeLixskYbdkiAHmhBVMa2Pdi85YPFqw3Ed", "amount": "38862003.71" }, - { "recipient": "Qary17o9qvZ2fifiVC8tF5zoBJm79n18zA", "amount": "3893972.772" }, - { "recipient": "QLvCWDGwzwpR29XgiThMGDX2vxyFW5rFHB", "amount": "8790585.239" }, - { "recipient": "Qgc77fSoAoUSVJfq62GxxTin6dBtU7Y6Hb", "amount": "194310018.5" }, - { "recipient": "QPmPKjwPLCuRei6abuhMtMocxAEeSuLVcv", "amount": "23317202.22" }, - { "recipient": "QcGfZePUN7JHs9WEEkJhXGzALy4JybiS3N", "amount": "194224522.1" }, - { "recipient": "QSeXGwk7eQjR8j7bndJST19qWtM2qnqL1u", "amount": "38862003.71" }, - { "recipient": "QU9i68h71nKTg4gwc5yJHzNRQdQEswP7Kn", "amount": "139592317.3" }, - { "recipient": "QdKrZGCkwXSSeXJhVA1idDXsA4VFtrjPHN", "amount": "15544801.48" }, - { "recipient": "QiYJ2B797xFpWYFu4XWivhGhyPXLU7S5Mr", "amount": "77724007.42" }, - { "recipient": "QWxqtsNXUWSjYns2wdngh4WBSWQzLoQHvx", "amount": "232613963.9" }, - { "recipient": "QTAGfu4FpTZ1bnvnd17YPtB3zabxfWKNeM", "amount": "101041209.6" }, - { "recipient": "QPtRxchgRdwdnoZRwhiAoa77AvVPNSRcQk", "amount": "114254290.9" }, - { "recipient": "QMcfoVc9Jat2pMFLHcuPEPnY6p6uBK6Dk7", "amount": "77724007.42" }, - { "recipient": "Qi84KosdwSWHZX3qz4WcMgqYGutBmj14dd", "amount": "15544801.48" }, - { "recipient": "QjAtcHsgig2tvdGr5tR4oGmRarhuojrAK1", "amount": "2883560.675" }, - { "recipient": "QPJPNLP2NMHu5athB7ydezdTA6zviCV378", "amount": "6373368.608" }, - { "recipient": "QfVLpmLbuUnA1JEe9FmeUAzihoBvqYDp8B", "amount": "15544801.48" }, - { "recipient": "QVVFdy6VLFqAFCb6XSBJLLZybiKgfgDDZV", "amount": "10725913.02" }, - { "recipient": "QVFXyeG1xpAR8Xg3u7oAmW8unueGAfeaKi", "amount": "31221733.78" }, - { "recipient": "QdtQtrM1h3TLtwAGCNyoTrW5HyiPRLhrPq", "amount": "138426457.2" }, - { "recipient": "QMukUMr84Mi2niz6rdhEJMkKJBve7uuRfe", "amount": "116586011.1" }, - { "recipient": "QZR8c7dmfwqGPujebFH1miQToJZ4JQfU1X", "amount": "217938116.8" }, - { "recipient": "QVV5Uu8eCxufTrBtquDKA96d7Kk8S4V7yX", "amount": "40091961.25" }, - { "recipient": "QY9YdgfTEUFvQ2UJszGS63qkwdENkW1PQ5", "amount": "154670774.8" }, - { "recipient": "QNgiswyhVyNJG4UMzvoSf29wDvGZqqs7WG", "amount": "11658601.11" }, - { "recipient": "QabjgFiY34oihNkUcy9hpFjQdCaypCShMe", "amount": "54406805.19" }, - { "recipient": "QionidPRekdshCTRL3c7idWWRAqGYcKaFN", "amount": "7772400.742" }, - { "recipient": "QcJdBJiVgiNBNg6ZwZAiEfYDMi5ZTQaYAa", "amount": "81386689.86" }, - { "recipient": "QNc8XMpPwM1HESwB7kqw8HoQ5sK2miZ2un", "amount": "190423818.2" }, - { "recipient": "QUP1SeaNw7CvCnmDp5ai3onWYwThS4GEpu", "amount": "3886200.371" }, - { "recipient": "QinToqEztNN1TsLdQEuzTHh7vUrEo6JTU2", "amount": "102440241.8" }, - { "recipient": "QcLJYLV4RD4GmPcoNnh7dQrWeYgiiPiqFQ", "amount": "32644083.11" }, - { "recipient": "QdYdYGYfgmMX4jQNWMZqLr81R3HdnuiKkv", "amount": "76169527.27" }, - { "recipient": "Qi62mUW5zfJhgRL8FRmCpjSCCnSKtf76S6", "amount": "76169527.27" }, - { "recipient": "QgFkxqQGkLW6CD95N2zTnT1PPqb9nxWp6b", "amount": "76169527.27" }, - { "recipient": "QfNUBudYsrrq27YqiHGLUg6BtG52W1W1ci", "amount": "15544801.48" }, - { "recipient": "QPSFoexnGoMH7EPdg72dM7SvqA7d4M2cu7", "amount": "37307523.56" }, - { "recipient": "QQxt5WMvoJ2TNScAzcoxHXPnLTeQ43nQ7N", "amount": "21995894.1" }, - { "recipient": "QicpACxck2oDYpzP8iWRQYD4oirCtvjok9", "amount": "93268808.9" }, - { "recipient": "QVTJkdQkTGgqEED9kAsp4BZbYNJqWfhgGw", "amount": "153909079.5" }, - { "recipient": "QQL5vCkhpXnP9F4wqNiBQsNaCocmRcDSUY", "amount": "15512934.64" }, - { "recipient": "QSvEex3p2LaZCVBaCyL8MpYsEpHLwed17r", "amount": "155448014.8" }, - { "recipient": "Qb3Xv96GucQpBG8n96QVFgcs2xXsEWW4CE", "amount": "38862003.71" }, - { "recipient": "QdRua9MqXufALpQFDeYiQDYk3EBGdwGXSx", "amount": "230303229.1" }, - { "recipient": "Qh16Umei91JqiHEVWV8AC6ED9aBqbDYuph", "amount": "231073474" }, - { "recipient": "QMu6HXfZCnwaNmyFjjhWTYAUW7k1x7PoVr", "amount": "231073474" }, - { "recipient": "QgcphUTiVHHfHg8e1LVgg5jujVES7ZDUTr", "amount": "115031531" }, - { "recipient": "QbQk9s4j4EAxAguBhmqA8mdtTct3qGnsrx", "amount": "138348733.2" }, - { "recipient": "QT79PhvBwE6vFzfZ4oh5wdKVsEazZuVJFy", "amount": "6360421.343" } + { "type": "ISSUE_ASSET", "owner": "QLpLzqs4DW1FNJByeJ63qaqw3eAYCxfkjR", "assetName": "QORA", "description": "QORA coin", "quantity": 10000000000, "isDivisible": true, "fee": 0, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC" }, + { "type": "GENESIS", "recipient": "QUD9y7NZqTtNwvSAUfewd7zKUGoVivVnTW", "amount": "7032468.191" }, + { "type": "GENESIS", "recipient": "QVafvKkE5bZTkq8PcXvdaxwuLNN2DGCwYk", "amount": "1716146.084" }, + { "type": "GENESIS", "recipient": "QV42QQP7frYWqsVq536g7zSk97fUpf2ZSN", "amount": "5241707.06" }, + { "type": "GENESIS", "recipient": "QgkLTm5GkepJpgr53nAgUyYRsvmyHpb2zT", "amount": "854964.0816" }, + { "type": "GENESIS", "recipient": "Qc8kN338XQULMBuUa6mTqL5tipvELDhzeZ", "amount": "769467.6734" }, + { "type": "GENESIS", "recipient": "QQ81BA75jZcpjQBLZE1qcHrXV8ARC1DEec", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QeoSe4DscWX4AFkNBCdm4WS1V7QkUFSQLP", "amount": "854968.3564" }, + { "type": "GENESIS", "recipient": "Qdfu3Eh21ZVHNDY1xyNaFqTTEYscSmfSsm", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QeDSr4abXKRg9j5hTN3TK9UGuH3umThZ42", "amount": "4445813.224" }, + { "type": "GENESIS", "recipient": "QQKDuo1txYB9E2xim79YVR6SQ1ZbJtJtFX", "amount": "47023024.49" }, + { "type": "GENESIS", "recipient": "QLeaeGr4CDA95FmeMtFh8okJRMLoq8Cge5", "amount": "170992816.3" }, + { "type": "GENESIS", "recipient": "QSwN5oa8ZHWJmc6FeAJ8Xr1SHaEuSahw1J", "amount": "3419856.326" }, + { "type": "GENESIS", "recipient": "QWnoGd4a7iXqQmNEpUtCb1x7nWgcya8QbE", "amount": "17056533.43" }, + { "type": "GENESIS", "recipient": "QbJqhsJjcy3vkzsJ1kHvgn26pQF3sZEypc", "amount": "42705455.87" }, + { "type": "GENESIS", "recipient": "QiBhBcseKzaDnHKyqEJs8z1Xx2rSb9XhBr", "amount": "141069073.5" }, + { "type": "GENESIS", "recipient": "QTwYwxBhzivFEWY5yfzyz1pqhJ8XCroKwv", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QfikxUU15Dy1oxbcDNEcLeU5cHvbrceq3A", "amount": "17099281.63" }, + { "type": "GENESIS", "recipient": "QhdqBmKZeQ3Hg1XUuR5nKtAkw47tuoRi2q", "amount": "12824461.22" }, + { "type": "GENESIS", "recipient": "QaVNyTqsTHA6JWMcqntcJf1u9c3qid76xH", "amount": "128244612.2" }, + { "type": "GENESIS", "recipient": "QYaDa7bmgo5L9qkcfJKjhPPrQkvGjEoc7y", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QQPddvWaYf4pbCyVHEVoyfC72EiaAv4JhT", "amount": "25648922.45" }, + { "type": "GENESIS", "recipient": "QSQpTNtTZMwaDuNq56Jz73KHWXaey9JrT1", "amount": "26341443.35" }, + { "type": "GENESIS", "recipient": "QVjcFWE6TnGePGJEtbNc1thwD2sgHBLvUV", "amount": "42940528.25" }, + { "type": "GENESIS", "recipient": "Qga93mWNqTuJYx6o33vjUpFH7Cn4sxLyoG", "amount": "2564892.245" }, + { "type": "GENESIS", "recipient": "QXyHKyQPJnb4ejyTkvS26x9sjWnhTTJ1Uc", "amount": "10259568.98" }, + { "type": "GENESIS", "recipient": "QLurSSgJvW7WXHDFSobgfakgqXxjoZzwUH", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QadxfiARcsmwzE93wqq82yXFi3ykM2qdtS", "amount": "79118376.11" }, + { "type": "GENESIS", "recipient": "QRHhhtz3Cv9RPKB1QBBfkRmRfpXx8vkRa5", "amount": "22435418.54" }, + { "type": "GENESIS", "recipient": "Qh8UnEs55n8jcnBaBwVtrTGkFFFBDyrMqH", "amount": "128757590.7" }, + { "type": "GENESIS", "recipient": "QhF7Fu3f54CTYA7zBQ223NQEssi2yAbAcx", "amount": "258481290.8" }, + { "type": "GENESIS", "recipient": "QPk9VB6tigoifrUYQrw4arBNk7i8HEgsDD", "amount": "128244612.2" }, + { "type": "GENESIS", "recipient": "QXWJnEPsdtaLQAEutJFR4ySiMUJCWDzZJX", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QVFs42gM4Cixf4Y5vDFvKKxRAamUPMCAVq", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "Qec5ueWc4rcBrty47GZfFSqvLymxvcycFm", "amount": "129091026.7" }, + { "type": "GENESIS", "recipient": "QfYiztbDz1Nb9EMhgHidLycvuPN8HEcHEj", "amount": "128244612.2" }, + { "type": "GENESIS", "recipient": "QPdWsZtaZcAKqk2HWVhEVbws4qG5KUTXmg", "amount": "179285967.9" }, + { "type": "GENESIS", "recipient": "QVkNs5NcwQpsrCXpWzuMXkMehJr5mkvLVy", "amount": "8558190.456" }, + { "type": "GENESIS", "recipient": "Qg19DzyEfyZANx6JLy4GrSGF5LuZ2MLqyZ", "amount": "42748204.08" }, + { "type": "GENESIS", "recipient": "Qf3A8L5WJNHt1xZxmayrTp2d5owzdkcxM6", "amount": "50519827.58" }, + { "type": "GENESIS", "recipient": "QeKR4W6qkFJGF7Hmu7rSUzTSQiqJzZLXdt", "amount": "10216820.77" }, + { "type": "GENESIS", "recipient": "QWg7T5i3uBY3xeBLFTLYYruR15Ln11vwo4", "amount": "170992816.3" }, + { "type": "GENESIS", "recipient": "QUYdM5fHECPZxKQQAmoxoQa2aWg8TZYfPw", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QjhfEZCgrjUbnLRnWqWxzyYqKQpjjxkuA8", "amount": "86665653.61" }, + { "type": "GENESIS", "recipient": "QMA53u3wrzDoxC57CWUJePNdR8FoqinqUS", "amount": "85496408.16" }, + { "type": "GENESIS", "recipient": "QSuCp6mB5zNNeJKD62aq2hR9h84ks1WhHf", "amount": "161588211.4" }, + { "type": "GENESIS", "recipient": "QS2tCUk7GQefg4zGewwrumxSPmN6fgA7Xc", "amount": "170992816.3" }, + { "type": "GENESIS", "recipient": "Qcn6FZRxAgp3japtvjgUkBY6KPfbPZMZtM", "amount": "170992816.3" }, + { "type": "GENESIS", "recipient": "QZrmXZkRmjV2GwMt72Rr1ZqHJjv8raDk5J", "amount": "17099281.63" }, + { "type": "GENESIS", "recipient": "QeZzwGDfAHa132jb6r4rQHbgJstLuT8QJ3", "amount": "255875360.3" }, + { "type": "GENESIS", "recipient": "Qj3L139sMMuFvvjKQDwRnoSgKUnoMhDQs5", "amount": "76946767.34" }, + { "type": "GENESIS", "recipient": "QWJvpvbFRZHu7LRbY5MjzvrMBgzJNFYjCX", "amount": "178251461.4" }, + { "type": "GENESIS", "recipient": "QRyECqW54ywKVt4kZTEXyRY17aaFUaxzc4", "amount": "8772355.539" }, + { "type": "GENESIS", "recipient": "QgpH3K3ArkQTg15xjKqGq3BRgE3aNH9Q2P", "amount": "46766535.26" }, + { "type": "GENESIS", "recipient": "QVZ6pxi8e3K3S44zLbnrLSLwSoYT8CWbwV", "amount": "233172022.2" }, + { "type": "GENESIS", "recipient": "QNbA69dbnmwqJHLQeS9v63hSLZXXGkmtC6", "amount": "46626632.05" }, + { "type": "GENESIS", "recipient": "QgzudSKbcLUeQUhFngotVswDSkbU42dSMr", "amount": "83786479.99" }, + { "type": "GENESIS", "recipient": "QfkQ2UzKMBGPwj8Sm31SArjtXoka1ubU3i", "amount": "116345066.7" }, + { "type": "GENESIS", "recipient": "QgxHHNwawZeTmQ3i5d9enchi4T9VmzNZ5k", "amount": "155448014.8" }, + { "type": "GENESIS", "recipient": "QMNugJWNsLuV4Qmbzdf8r8RMEdXk5PNM69", "amount": "155448014.8" }, + { "type": "GENESIS", "recipient": "QVhWuJkCjStNMV4U8PtNM9Qz4PvLAEtVSj", "amount": "101041209.6" }, + { "type": "GENESIS", "recipient": "QXjNcckFG9gTr9YbiA3RrRhn3mPJ9zyR4G", "amount": "3108960.297" }, + { "type": "GENESIS", "recipient": "QThnuBadmExtxk81vhFKimSzbPaPcuPAdm", "amount": "155448014.8" }, + { "type": "GENESIS", "recipient": "QRc6sQthLHjfkmm2BUhu74g33XtkDoB7JP", "amount": "77773983.95" }, + { "type": "GENESIS", "recipient": "QcDLhirHkSbR4TLYeShLzHw61B8UGTFusk", "amount": "23317202.22" }, + { "type": "GENESIS", "recipient": "QXRnsXE6srHEf2abGh4eogs2mRsmNiuw6V", "amount": "5440680.519" }, + { "type": "GENESIS", "recipient": "QRJmEswbDw4x1kwsLyxtMS9533fv5cDvQV", "amount": "3886200.371" }, + { "type": "GENESIS", "recipient": "Qg43mCzWmFVwhVfx34g6shXnSU7U7amJNx", "amount": "6217920.593" }, + { "type": "GENESIS", "recipient": "QQ9PveFTW64yUcXEE6AxhokWCwhmn8F2TD", "amount": "8549640.816" }, + { "type": "GENESIS", "recipient": "QQaxJuTkW5XXn4DhhRekXpdXaWcsxEfCNG", "amount": "3886200.371" }, + { "type": "GENESIS", "recipient": "QifWFqW8XWL5mcNxtdr5z1LVC7XUu9tNSK", "amount": "3116732.697" }, + { "type": "GENESIS", "recipient": "QavhBKRN4vuyzHNNqcWxjcohRAJNTdTmh4", "amount": "154670774.8" }, + { "type": "GENESIS", "recipient": "QMQyR3Hybof8WpQsXPxh19AZFCj4Z4mmke", "amount": "77724007.42" }, + { "type": "GENESIS", "recipient": "QbT3GGjp1esTXtowVk2XCtBsKoRB8mkP61", "amount": "77724007.42" }, + { "type": "GENESIS", "recipient": "QT13tVMZEtbrgJEsBBcTtnyqGveC7mtqAb", "amount": "23317202.22" }, + { "type": "GENESIS", "recipient": "QegT2Ws5YjLQzEZ9YMzWsAZMBE8cAygHZN", "amount": "12606834" }, + { "type": "GENESIS", "recipient": "QXoKRBJiJGKwvdA3jkmoUhkM7y6vuMp2pn", "amount": "65117173.41" }, + { "type": "GENESIS", "recipient": "QY6SpdBzUev9ziqkmyaxESZSbdKwqGdedn", "amount": "89382608.53" }, + { "type": "GENESIS", "recipient": "QeMxyt1nEE7tbFbioc87xhiKb4szx5DsjY", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "QcTp3THGZvJ42f2mWsQrawGvgBoSHgHZyk", "amount": "39639243.78" }, + { "type": "GENESIS", "recipient": "QjSH91mTDN6TeV1naAcfwPhmRogufV4n1u", "amount": "23317202.22" }, + { "type": "GENESIS", "recipient": "QiFLELeLm2TFWsnknzje51wMdt3Srkjz8g", "amount": "1554480.148" }, + { "type": "GENESIS", "recipient": "QhxtJ3vvhsvVU9x2j5n2R3TXzutfLMUvBR", "amount": "23317202.22" }, + { "type": "GENESIS", "recipient": "QUtUSNQfqexZZkaZ2s9LcpqjnTezPTnuAx", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "Qg6sPLxNMYxjEDGLLaFkkWx6ip3py5fLEt", "amount": "777240.0742" }, + { "type": "GENESIS", "recipient": "QeLixskYbdkiAHmhBVMa2Pdi85YPFqw3Ed", "amount": "38862003.71" }, + { "type": "GENESIS", "recipient": "Qary17o9qvZ2fifiVC8tF5zoBJm79n18zA", "amount": "3893972.772" }, + { "type": "GENESIS", "recipient": "QLvCWDGwzwpR29XgiThMGDX2vxyFW5rFHB", "amount": "8790585.239" }, + { "type": "GENESIS", "recipient": "Qgc77fSoAoUSVJfq62GxxTin6dBtU7Y6Hb", "amount": "194310018.5" }, + { "type": "GENESIS", "recipient": "QPmPKjwPLCuRei6abuhMtMocxAEeSuLVcv", "amount": "23317202.22" }, + { "type": "GENESIS", "recipient": "QcGfZePUN7JHs9WEEkJhXGzALy4JybiS3N", "amount": "194224522.1" }, + { "type": "GENESIS", "recipient": "QSeXGwk7eQjR8j7bndJST19qWtM2qnqL1u", "amount": "38862003.71" }, + { "type": "GENESIS", "recipient": "QU9i68h71nKTg4gwc5yJHzNRQdQEswP7Kn", "amount": "139592317.3" }, + { "type": "GENESIS", "recipient": "QdKrZGCkwXSSeXJhVA1idDXsA4VFtrjPHN", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "QiYJ2B797xFpWYFu4XWivhGhyPXLU7S5Mr", "amount": "77724007.42" }, + { "type": "GENESIS", "recipient": "QWxqtsNXUWSjYns2wdngh4WBSWQzLoQHvx", "amount": "232613963.9" }, + { "type": "GENESIS", "recipient": "QTAGfu4FpTZ1bnvnd17YPtB3zabxfWKNeM", "amount": "101041209.6" }, + { "type": "GENESIS", "recipient": "QPtRxchgRdwdnoZRwhiAoa77AvVPNSRcQk", "amount": "114254290.9" }, + { "type": "GENESIS", "recipient": "QMcfoVc9Jat2pMFLHcuPEPnY6p6uBK6Dk7", "amount": "77724007.42" }, + { "type": "GENESIS", "recipient": "Qi84KosdwSWHZX3qz4WcMgqYGutBmj14dd", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "QjAtcHsgig2tvdGr5tR4oGmRarhuojrAK1", "amount": "2883560.675" }, + { "type": "GENESIS", "recipient": "QPJPNLP2NMHu5athB7ydezdTA6zviCV378", "amount": "6373368.608" }, + { "type": "GENESIS", "recipient": "QfVLpmLbuUnA1JEe9FmeUAzihoBvqYDp8B", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "QVVFdy6VLFqAFCb6XSBJLLZybiKgfgDDZV", "amount": "10725913.02" }, + { "type": "GENESIS", "recipient": "QVFXyeG1xpAR8Xg3u7oAmW8unueGAfeaKi", "amount": "31221733.78" }, + { "type": "GENESIS", "recipient": "QdtQtrM1h3TLtwAGCNyoTrW5HyiPRLhrPq", "amount": "138426457.2" }, + { "type": "GENESIS", "recipient": "QMukUMr84Mi2niz6rdhEJMkKJBve7uuRfe", "amount": "116586011.1" }, + { "type": "GENESIS", "recipient": "QZR8c7dmfwqGPujebFH1miQToJZ4JQfU1X", "amount": "217938116.8" }, + { "type": "GENESIS", "recipient": "QVV5Uu8eCxufTrBtquDKA96d7Kk8S4V7yX", "amount": "40091961.25" }, + { "type": "GENESIS", "recipient": "QY9YdgfTEUFvQ2UJszGS63qkwdENkW1PQ5", "amount": "154670774.8" }, + { "type": "GENESIS", "recipient": "QNgiswyhVyNJG4UMzvoSf29wDvGZqqs7WG", "amount": "11658601.11" }, + { "type": "GENESIS", "recipient": "QabjgFiY34oihNkUcy9hpFjQdCaypCShMe", "amount": "54406805.19" }, + { "type": "GENESIS", "recipient": "QionidPRekdshCTRL3c7idWWRAqGYcKaFN", "amount": "7772400.742" }, + { "type": "GENESIS", "recipient": "QcJdBJiVgiNBNg6ZwZAiEfYDMi5ZTQaYAa", "amount": "81386689.86" }, + { "type": "GENESIS", "recipient": "QNc8XMpPwM1HESwB7kqw8HoQ5sK2miZ2un", "amount": "190423818.2" }, + { "type": "GENESIS", "recipient": "QUP1SeaNw7CvCnmDp5ai3onWYwThS4GEpu", "amount": "3886200.371" }, + { "type": "GENESIS", "recipient": "QinToqEztNN1TsLdQEuzTHh7vUrEo6JTU2", "amount": "102440241.8" }, + { "type": "GENESIS", "recipient": "QcLJYLV4RD4GmPcoNnh7dQrWeYgiiPiqFQ", "amount": "32644083.11" }, + { "type": "GENESIS", "recipient": "QdYdYGYfgmMX4jQNWMZqLr81R3HdnuiKkv", "amount": "76169527.27" }, + { "type": "GENESIS", "recipient": "Qi62mUW5zfJhgRL8FRmCpjSCCnSKtf76S6", "amount": "76169527.27" }, + { "type": "GENESIS", "recipient": "QgFkxqQGkLW6CD95N2zTnT1PPqb9nxWp6b", "amount": "76169527.27" }, + { "type": "GENESIS", "recipient": "QfNUBudYsrrq27YqiHGLUg6BtG52W1W1ci", "amount": "15544801.48" }, + { "type": "GENESIS", "recipient": "QPSFoexnGoMH7EPdg72dM7SvqA7d4M2cu7", "amount": "37307523.56" }, + { "type": "GENESIS", "recipient": "QQxt5WMvoJ2TNScAzcoxHXPnLTeQ43nQ7N", "amount": "21995894.1" }, + { "type": "GENESIS", "recipient": "QicpACxck2oDYpzP8iWRQYD4oirCtvjok9", "amount": "93268808.9" }, + { "type": "GENESIS", "recipient": "QVTJkdQkTGgqEED9kAsp4BZbYNJqWfhgGw", "amount": "153909079.5" }, + { "type": "GENESIS", "recipient": "QQL5vCkhpXnP9F4wqNiBQsNaCocmRcDSUY", "amount": "15512934.64" }, + { "type": "GENESIS", "recipient": "QSvEex3p2LaZCVBaCyL8MpYsEpHLwed17r", "amount": "155448014.8" }, + { "type": "GENESIS", "recipient": "Qb3Xv96GucQpBG8n96QVFgcs2xXsEWW4CE", "amount": "38862003.71" }, + { "type": "GENESIS", "recipient": "QdRua9MqXufALpQFDeYiQDYk3EBGdwGXSx", "amount": "230303229.1" }, + { "type": "GENESIS", "recipient": "Qh16Umei91JqiHEVWV8AC6ED9aBqbDYuph", "amount": "231073474" }, + { "type": "GENESIS", "recipient": "QMu6HXfZCnwaNmyFjjhWTYAUW7k1x7PoVr", "amount": "231073474" }, + { "type": "GENESIS", "recipient": "QgcphUTiVHHfHg8e1LVgg5jujVES7ZDUTr", "amount": "115031531" }, + { "type": "GENESIS", "recipient": "QbQk9s4j4EAxAguBhmqA8mdtTct3qGnsrx", "amount": "138348733.2" }, + { "type": "GENESIS", "recipient": "QT79PhvBwE6vFzfZ4oh5wdKVsEazZuVJFy", "amount": "6360421.343" } ] }, "featureTriggers": { - "message": { "height": "99000" }, - "AT": { "height": "99000" }, - "assets": { "timestamp": "0" }, - "voting": { "timestamp": "1403715600000" }, - "arbitrary": { "timestamp": "1405702800000" }, - "powfix": { "timestamp": "1456426800000" }, - "v2" : { "timestamp": "1552500000000" } + "messageHeight": 99000, + "atHeight": 99000, + "assetsTimestamp": 0, + "votingTimestamp": "1403715600000", + "arbitraryTimestamp": "1405702800000", + "powfixTimestamp": "1456426800000", + "v2Timestamp": "1552500000000" } } diff --git a/src/main/java/org/qora/block/GenesisBlock.java b/src/main/java/org/qora/block/GenesisBlock.java index c3cc1af8..7b633298 100644 --- a/src/main/java/org/qora/block/GenesisBlock.java +++ b/src/main/java/org/qora/block/GenesisBlock.java @@ -3,6 +3,7 @@ package org.qora.block; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -85,7 +86,7 @@ public class GenesisBlock extends Block { info.timestamp = System.currentTimeMillis(); } - transactionsData = Arrays.asList(info.transactions); + transactionsData = new ArrayList(Arrays.asList(info.transactions)); // Add default values to transactions transactionsData.stream().forEach(transactionData -> { @@ -112,7 +113,7 @@ public class GenesisBlock extends Block { } // Convert ISSUE_ASSET transactions into initial assets - issueAssetTransactions.stream().map(transactionData -> { + initialAssets = issueAssetTransactions.stream().map(transactionData -> { IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData; return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(), diff --git a/src/main/java/org/qora/data/transaction/TransactionData.java b/src/main/java/org/qora/data/transaction/TransactionData.java index 02e90f99..fdcd50e8 100644 --- a/src/main/java/org/qora/data/transaction/TransactionData.java +++ b/src/main/java/org/qora/data/transaction/TransactionData.java @@ -168,6 +168,10 @@ public abstract class TransactionData { @Override public boolean equals(Object other) { + // Comparing exact same object + if (this == other) + return true; + // If we don't have a signature then fail if (this.signature == null) return false; diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java index 01416ad5..0a5aca53 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java @@ -213,7 +213,7 @@ public class HSQLDBAssetRepository implements AssetRepository { @Override public List 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"; if (reverse != null && reverse) sql += " DESC"; diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java index 4da188d9..b7a23ff4 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java @@ -3,9 +3,7 @@ package org.qora.repository.hsqldb; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Calendar; import java.util.List; import org.qora.data.block.BlockData; @@ -15,6 +13,9 @@ import org.qora.repository.BlockRepository; import org.qora.repository.DataException; 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 { 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); byte[] transactionsSignature = resultSet.getBytes(5); 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); byte[] generatorPublicKey = resultSet.getBytes(9); byte[] generatorSignature = resultSet.getBytes(10); @@ -92,7 +93,9 @@ public class HSQLDBBlockRepository implements BlockRepository { @Override 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) return 0; @@ -104,7 +107,7 @@ public class HSQLDBBlockRepository implements BlockRepository { @Override 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) return 0; @@ -153,7 +156,7 @@ public class HSQLDBBlockRepository implements BlockRepository { saveHelper.bind("signature", blockData.getSignature()).bind("version", blockData.getVersion()).bind("reference", blockData.getReference()) .bind("transaction_count", blockData.getTransactionCount()).bind("total_fees", blockData.getTotalFees()) .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("AT_count", blockData.getATCount()).bind("AT_fees", blockData.getATFees()); diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java index bcb201a6..6338d536 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -109,7 +109,7 @@ public class HSQLDBDatabaseUpdates { 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 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 ATState AS BLOB(1M)"); // 16bit * 8 + 16bit * 4 + 16bit * 4 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)"); // For finding blocks by reference, e.g. child blocks. 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. stmt.execute("SET TABLE Blocks NEW SPACE"); break; @@ -583,6 +585,11 @@ public class HSQLDBDatabaseUpdates { stmt.execute("ALTER TABLE Groups ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0"); break; + case 37: + // Performance-improving INDEX + stmt.execute("CREATE INDEX IF NOT EXISTS BlockGenerationHeightIndex ON Blocks (generation, height)"); + break; + default: // nothing to do return false; diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java index 455a53d6..c9fa6f6d 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java @@ -7,6 +7,9 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Savepoint; import java.sql.Statement; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; import java.util.ArrayDeque; import java.util.Deque; import java.util.TimeZone; @@ -385,4 +388,23 @@ public class HSQLDBRepository implements Repository { 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(); + } + } \ No newline at end of file diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java index 7a128058..a13c6e3a 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java @@ -187,7 +187,12 @@ public class HSQLDBTransactionRepository implements TransactionRepository { try { // 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); - } 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"); } } @@ -699,7 +704,12 @@ public class HSQLDBTransactionRepository implements TransactionRepository { try { 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"); } } diff --git a/src/main/java/org/qora/transform/transaction/AtTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/AtTransactionTransformer.java index 5598c815..5cf8f5b0 100644 --- a/src/main/java/org/qora/transform/transaction/AtTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/AtTransactionTransformer.java @@ -1,12 +1,28 @@ package org.qora.transform.transaction; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; import java.nio.ByteBuffer; +import org.qora.data.transaction.ATTransactionData; import org.qora.data.transaction.TransactionData; 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 { + 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; // Property lengths @@ -15,12 +31,48 @@ public class AtTransactionTransformer extends TransactionTransformer { } public static int getDataLength(TransactionData transactionData) throws TransformationException { - // AT Transactions aren't serialized so don't take up any space in the block. - return 0; + ATTransactionData atTransactionData = (ATTransactionData) transactionData; + + return getBaseLength(transactionData) + EXTRAS_LENGTH + atTransactionData.getMessage().length; } 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); + } } } diff --git a/src/main/java/org/qora/transform/transaction/TransactionTransformer.java b/src/main/java/org/qora/transform/transaction/TransactionTransformer.java index 147572af..d79d1a67 100644 --- a/src/main/java/org/qora/transform/transaction/TransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/TransactionTransformer.java @@ -210,7 +210,15 @@ public abstract class TransactionTransformer extends Transformer { return (TransactionData) method.invoke(null, byteBuffer); } catch (BufferUnderflowException e) { 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"); } } @@ -231,7 +239,12 @@ public abstract class TransactionTransformer extends Transformer { try { Method method = subclassInfos[type.value].getDataLengthMethod; 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"); } } @@ -242,7 +255,12 @@ public abstract class TransactionTransformer extends Transformer { try { Method method = subclassInfos[type.value].toBytesMethod; 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"); } } @@ -262,7 +280,12 @@ public abstract class TransactionTransformer extends Transformer { try { Method method = subclassInfos[type.value].toBytesForSigningImplMethod; 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"); } } diff --git a/src/main/java/org/qora/transform/transaction/VoteOnPollTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/VoteOnPollTransactionTransformer.java index 367d05b4..2f0b8ed4 100644 --- a/src/main/java/org/qora/transform/transaction/VoteOnPollTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/VoteOnPollTransactionTransformer.java @@ -80,8 +80,6 @@ public class VoteOnPollTransactionTransformer extends TransactionTransformer { transformCommonBytes(transactionData, bytes); - bytes.write(voteOnPollTransactionData.getVoterPublicKey()); - Serialization.serializeSizedString(bytes, voteOnPollTransactionData.getPollName()); bytes.write(Ints.toByteArray(voteOnPollTransactionData.getOptionIndex())); diff --git a/src/main/java/org/qora/v1feeder.java b/src/main/java/org/qora/v1feeder.java index ca4f08d5..9d8f0459 100644 --- a/src/main/java/org/qora/v1feeder.java +++ b/src/main/java/org/qora/v1feeder.java @@ -15,6 +15,7 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.Security; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -23,6 +24,8 @@ import java.util.Map; import org.apache.logging.log4j.LogManager; 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.JSONObject; import org.json.simple.JSONValue; @@ -44,6 +47,7 @@ import org.qora.repository.Repository; import org.qora.repository.RepositoryFactory; import org.qora.repository.RepositoryManager; import org.qora.repository.hsqldb.HSQLDBRepositoryFactory; +import org.qora.settings.Settings; import org.qora.transform.TransformationException; import org.qora.transform.block.BlockTransformer; import org.qora.transform.transaction.AtTransactionTransformer; @@ -57,6 +61,11 @@ import com.google.common.primitives.Ints; 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 int INACTIVITY_TIMEOUT = 60 * 1000; // milliseconds @@ -529,6 +538,11 @@ public class v1feeder extends Thread { String legacyATPathname = args[0]; readLegacyATs(legacyATPathname); + Security.insertProviderAt(new BouncyCastleProvider(), 0); + Security.insertProviderAt(new BouncyCastleJsseProvider(), 1); + + Settings.getInstance(); + try { RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(Controller.connectionUrl); RepositoryManager.setRepositoryFactory(repositoryFactory);