diff -Nru bitshares-2-2.15.294+1027/debian/changelog bitshares-2-2.15.306/debian/changelog --- bitshares-2-2.15.294+1027/debian/changelog 2015-10-28 14:23:34.000000000 +0000 +++ bitshares-2-2.15.306/debian/changelog 2015-11-02 20:58:36.000000000 +0000 @@ -1,3 +1,9 @@ +bitshares-2 (2.15.306-0~wily) wily; urgency=medium + + * New release + + -- Scott Howard Mon, 02 Nov 2015 15:47:50 -0500 + bitshares-2 (2.15.294+1027-0~wily) wily; urgency=medium * New Release diff -Nru bitshares-2-2.15.294+1027/debian/rules bitshares-2-2.15.306/debian/rules --- bitshares-2-2.15.294+1027/debian/rules 2015-10-28 14:18:56.000000000 +0000 +++ bitshares-2-2.15.306/debian/rules 2015-11-02 20:55:02.000000000 +0000 @@ -5,7 +5,7 @@ export DH_VERBOSE=1 VERSION=$(shell dpkg-parsechangelog | sed -n -e 's/^Version: \([0-9\.\+]*\).*/\1/p') -TAGVERSION=2.0.151021#temporary, reset next version bump +#TAGVERSION=2.0.151027#temporary, reset next version bump #sometimes out-of-tree builds have bugs %: @@ -32,5 +32,5 @@ git pull git submodule init git submodule update --init --recursive - git checkout v${TAGVERSION} + git checkout v${VERSION} cd .. && tar -czf bitshares-2_${VERSION}.orig.tar.gz bitshares-2 --exclude=debian/ diff -Nru bitshares-2-2.15.294+1027/.git/FETCH_HEAD bitshares-2-2.15.306/.git/FETCH_HEAD --- bitshares-2-2.15.294+1027/.git/FETCH_HEAD 2015-10-28 14:18:58.000000000 +0000 +++ bitshares-2-2.15.306/.git/FETCH_HEAD 2015-11-02 20:55:22.000000000 +0000 @@ -1,4 +1,4 @@ -0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 branch 'bitshares' of https://github.com/bitshares/bitshares-2 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 branch 'bitshares' of https://github.com/bitshares/bitshares-2 b13009b973288a61bda050c9e4d559d529d5a03f not-for-merge branch 'assert_reflect' of https://github.com/bitshares/bitshares-2 a878b35232c2abc4740c4181a391b43d240f90c4 not-for-merge branch 'bitshares-fork-1' of https://github.com/bitshares/bitshares-2 5f79b662dcb28f9ab3e9fa5424f03ad73be185a0 not-for-merge branch 'bond' of https://github.com/bitshares/bitshares-2 @@ -10,8 +10,12 @@ a748d4cc1d62f71e6c7fe66dd84f906c6ae856f1 not-for-merge branch 'issue362' of https://github.com/bitshares/bitshares-2 fd06e83f20e2ad64d34b81eb069b6cb65fbdbb15 not-for-merge branch 'issue_299' of https://github.com/bitshares/bitshares-2 33fe8e9d7cb8c80ddd289d1886d64292b033d685 not-for-merge branch 'line_of_credit' of https://github.com/bitshares/bitshares-2 -285d061295243d06bd01b4413ecbfc6ee12e1a04 not-for-merge branch 'master' of https://github.com/bitshares/bitshares-2 +0874ee7f0c14db31957cd776c582b2fda0d479f3 not-for-merge branch 'master' of https://github.com/bitshares/bitshares-2 662959d3945eb2c3eb323bf23f3656678a8dc052 not-for-merge branch 'network_params' of https://github.com/bitshares/bitshares-2 +09855166a2eab59d03ad199ac308c856f6a72e9e not-for-merge branch 'newmaster' of https://github.com/bitshares/bitshares-2 6e01c31340360b64cbe23cf12349e5639b5f85e4 not-for-merge branch 'remove_pending' of https://github.com/bitshares/bitshares-2 b21fb0c3a8e7143fd9f34281cf9fa6c16ba7fad5 not-for-merge branch 'splitter' of https://github.com/bitshares/bitshares-2 3bc66e31a21d160073648f3dcef92266a975ea82 not-for-merge branch 'witness_schedule_refactor' of https://github.com/bitshares/bitshares-2 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 not-for-merge tag 'v2.0.151027' of https://github.com/bitshares/bitshares-2 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 not-for-merge tag 'v2.0.151101' of https://github.com/bitshares/bitshares-2 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 not-for-merge tag 'v2.15.306' of https://github.com/bitshares/bitshares-2 diff -Nru bitshares-2-2.15.294+1027/.git/HEAD bitshares-2-2.15.306/.git/HEAD --- bitshares-2-2.15.294+1027/.git/HEAD 2015-10-28 14:18:59.000000000 +0000 +++ bitshares-2-2.15.306/.git/HEAD 2015-11-02 20:55:24.000000000 +0000 @@ -1 +1 @@ -0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 Binary files /tmp/T63Rse5rsH/bitshares-2-2.15.294+1027/.git/index and /tmp/PIq2bxcOrk/bitshares-2-2.15.306/.git/index differ diff -Nru bitshares-2-2.15.294+1027/.git/logs/HEAD bitshares-2-2.15.306/.git/logs/HEAD --- bitshares-2-2.15.294+1027/.git/logs/HEAD 2015-10-28 14:18:59.000000000 +0000 +++ bitshares-2-2.15.306/.git/logs/HEAD 2015-11-02 20:55:24.000000000 +0000 @@ -10,3 +10,6 @@ ddd58e946a0d180eea8e5cc82b5d031136980531 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446041923 -0400 pull: Fast-forward 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446041938 -0400 checkout: moving from bitshares to bitshares 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446041939 -0400 checkout: moving from bitshares to v2.0.151021 +0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446497720 -0500 checkout: moving from 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 to bitshares +0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 2f83c4e4272ad97c704b611036efbf5aeebe1a93 Scott Howard 1446497723 -0500 pull: Fast-forward +2f83c4e4272ad97c704b611036efbf5aeebe1a93 2f83c4e4272ad97c704b611036efbf5aeebe1a93 Scott Howard 1446497724 -0500 checkout: moving from bitshares to v2.15.306 diff -Nru bitshares-2-2.15.294+1027/.git/logs/refs/heads/bitshares bitshares-2-2.15.306/.git/logs/refs/heads/bitshares --- bitshares-2-2.15.294+1027/.git/logs/refs/heads/bitshares 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/logs/refs/heads/bitshares 2015-11-02 20:55:23.000000000 +0000 @@ -1,3 +1,4 @@ 0000000000000000000000000000000000000000 8488731e377024fb1ceb738105fd53dac89d0f68 Scott Howard 1445371176 -0400 clone: from https://github.com/bitshares/bitshares-2.git 8488731e377024fb1ceb738105fd53dac89d0f68 ddd58e946a0d180eea8e5cc82b5d031136980531 Scott Howard 1445456887 -0400 pull: Fast-forward ddd58e946a0d180eea8e5cc82b5d031136980531 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446041923 -0400 pull: Fast-forward +0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 2f83c4e4272ad97c704b611036efbf5aeebe1a93 Scott Howard 1446497723 -0500 pull: Fast-forward diff -Nru bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/bitshares bitshares-2-2.15.306/.git/logs/refs/remotes/origin/bitshares --- bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/bitshares 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/logs/refs/remotes/origin/bitshares 2015-11-02 20:55:22.000000000 +0000 @@ -1,2 +1,3 @@ 8488731e377024fb1ceb738105fd53dac89d0f68 ddd58e946a0d180eea8e5cc82b5d031136980531 Scott Howard 1445456887 -0400 pull: fast-forward ddd58e946a0d180eea8e5cc82b5d031136980531 0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 Scott Howard 1446041923 -0400 pull: fast-forward +0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 2f83c4e4272ad97c704b611036efbf5aeebe1a93 Scott Howard 1446497722 -0500 pull: fast-forward diff -Nru bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/master bitshares-2-2.15.306/.git/logs/refs/remotes/origin/master --- bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/master 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/logs/refs/remotes/origin/master 2015-11-02 20:55:22.000000000 +0000 @@ -1 +1,2 @@ 4c09d6b8ed350ff5c7546e2c3fd15d0e6699daf2 285d061295243d06bd01b4413ecbfc6ee12e1a04 Scott Howard 1446041923 -0400 pull: fast-forward +285d061295243d06bd01b4413ecbfc6ee12e1a04 0874ee7f0c14db31957cd776c582b2fda0d479f3 Scott Howard 1446497722 -0500 pull: fast-forward diff -Nru bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/newmaster bitshares-2-2.15.306/.git/logs/refs/remotes/origin/newmaster --- bitshares-2-2.15.294+1027/.git/logs/refs/remotes/origin/newmaster 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/.git/logs/refs/remotes/origin/newmaster 2015-11-02 20:55:22.000000000 +0000 @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 09855166a2eab59d03ad199ac308c856f6a72e9e Scott Howard 1446497722 -0500 pull: storing head diff -Nru bitshares-2-2.15.294+1027/.git/modules/libraries/fc/HEAD bitshares-2-2.15.306/.git/modules/libraries/fc/HEAD --- bitshares-2-2.15.294+1027/.git/modules/libraries/fc/HEAD 2015-10-20 19:59:53.000000000 +0000 +++ bitshares-2-2.15.306/.git/modules/libraries/fc/HEAD 2015-11-02 20:55:24.000000000 +0000 @@ -1 +1 @@ -6495004302239ae0c775f05a0e78780c3b189502 +1e10d3dc4774426e735eb6aabd8e0aa43799fe30 Binary files /tmp/T63Rse5rsH/bitshares-2-2.15.294+1027/.git/modules/libraries/fc/index and /tmp/PIq2bxcOrk/bitshares-2-2.15.306/.git/modules/libraries/fc/index differ diff -Nru bitshares-2-2.15.294+1027/.git/modules/libraries/fc/logs/HEAD bitshares-2-2.15.306/.git/modules/libraries/fc/logs/HEAD --- bitshares-2-2.15.294+1027/.git/modules/libraries/fc/logs/HEAD 2015-10-20 19:59:53.000000000 +0000 +++ bitshares-2-2.15.306/.git/modules/libraries/fc/logs/HEAD 2015-11-02 20:55:24.000000000 +0000 @@ -1,2 +1,3 @@ 0000000000000000000000000000000000000000 1e10d3dc4774426e735eb6aabd8e0aa43799fe30 Scott Howard 1445371193 -0400 clone: from https://github.com/cryptonomex/fc.git 1e10d3dc4774426e735eb6aabd8e0aa43799fe30 6495004302239ae0c775f05a0e78780c3b189502 Scott Howard 1445371193 -0400 checkout: moving from master to 6495004302239ae0c775f05a0e78780c3b189502 +6495004302239ae0c775f05a0e78780c3b189502 1e10d3dc4774426e735eb6aabd8e0aa43799fe30 Scott Howard 1446497724 -0500 checkout: moving from 6495004302239ae0c775f05a0e78780c3b189502 to 1e10d3dc4774426e735eb6aabd8e0aa43799fe30 diff -Nru bitshares-2-2.15.294+1027/.git/modules/libraries/fc/modules/vendor/secp256k1-zkp/gitfile bitshares-2-2.15.306/.git/modules/libraries/fc/modules/vendor/secp256k1-zkp/gitfile --- bitshares-2-2.15.294+1027/.git/modules/libraries/fc/modules/vendor/secp256k1-zkp/gitfile 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/modules/libraries/fc/modules/vendor/secp256k1-zkp/gitfile 2015-11-02 20:55:23.000000000 +0000 @@ -1 +1 @@ -.git +vendor/secp256k1-zkp/.git diff -Nru bitshares-2-2.15.294+1027/.git/modules/libraries/fc/modules/vendor/websocketpp/gitfile bitshares-2-2.15.306/.git/modules/libraries/fc/modules/vendor/websocketpp/gitfile --- bitshares-2-2.15.294+1027/.git/modules/libraries/fc/modules/vendor/websocketpp/gitfile 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/modules/libraries/fc/modules/vendor/websocketpp/gitfile 2015-11-02 20:55:24.000000000 +0000 @@ -1 +1 @@ -.git +vendor/websocketpp/.git Binary files /tmp/T63Rse5rsH/bitshares-2-2.15.294+1027/.git/objects/pack/pack-88b0d39a3ea0cf68b092835d211ddaace2eff764.idx and /tmp/PIq2bxcOrk/bitshares-2-2.15.306/.git/objects/pack/pack-88b0d39a3ea0cf68b092835d211ddaace2eff764.idx differ Binary files /tmp/T63Rse5rsH/bitshares-2-2.15.294+1027/.git/objects/pack/pack-88b0d39a3ea0cf68b092835d211ddaace2eff764.pack and /tmp/PIq2bxcOrk/bitshares-2-2.15.306/.git/objects/pack/pack-88b0d39a3ea0cf68b092835d211ddaace2eff764.pack differ diff -Nru bitshares-2-2.15.294+1027/.git/refs/heads/bitshares bitshares-2-2.15.306/.git/refs/heads/bitshares --- bitshares-2-2.15.294+1027/.git/refs/heads/bitshares 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/heads/bitshares 2015-11-02 20:55:23.000000000 +0000 @@ -1 +1 @@ -0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 diff -Nru bitshares-2-2.15.294+1027/.git/refs/remotes/origin/bitshares bitshares-2-2.15.306/.git/refs/remotes/origin/bitshares --- bitshares-2-2.15.294+1027/.git/refs/remotes/origin/bitshares 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/remotes/origin/bitshares 2015-11-02 20:55:22.000000000 +0000 @@ -1 +1 @@ -0c3a7c4bc442133e1061d2ecffe20b8df40b8a90 +2f83c4e4272ad97c704b611036efbf5aeebe1a93 diff -Nru bitshares-2-2.15.294+1027/.git/refs/remotes/origin/master bitshares-2-2.15.306/.git/refs/remotes/origin/master --- bitshares-2-2.15.294+1027/.git/refs/remotes/origin/master 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/remotes/origin/master 2015-11-02 20:55:22.000000000 +0000 @@ -1 +1 @@ -285d061295243d06bd01b4413ecbfc6ee12e1a04 +0874ee7f0c14db31957cd776c582b2fda0d479f3 diff -Nru bitshares-2-2.15.294+1027/.git/refs/remotes/origin/newmaster bitshares-2-2.15.306/.git/refs/remotes/origin/newmaster --- bitshares-2-2.15.294+1027/.git/refs/remotes/origin/newmaster 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/remotes/origin/newmaster 2015-11-02 20:55:22.000000000 +0000 @@ -0,0 +1 @@ +09855166a2eab59d03ad199ac308c856f6a72e9e diff -Nru bitshares-2-2.15.294+1027/.git/refs/tags/v2.0.151027 bitshares-2-2.15.306/.git/refs/tags/v2.0.151027 --- bitshares-2-2.15.294+1027/.git/refs/tags/v2.0.151027 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/tags/v2.0.151027 2015-11-02 20:55:22.000000000 +0000 @@ -0,0 +1 @@ +2f83c4e4272ad97c704b611036efbf5aeebe1a93 diff -Nru bitshares-2-2.15.294+1027/.git/refs/tags/v2.0.151101 bitshares-2-2.15.306/.git/refs/tags/v2.0.151101 --- bitshares-2-2.15.294+1027/.git/refs/tags/v2.0.151101 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/tags/v2.0.151101 2015-11-02 20:55:22.000000000 +0000 @@ -0,0 +1 @@ +2f83c4e4272ad97c704b611036efbf5aeebe1a93 diff -Nru bitshares-2-2.15.294+1027/.git/refs/tags/v2.15.306 bitshares-2-2.15.306/.git/refs/tags/v2.15.306 --- bitshares-2-2.15.294+1027/.git/refs/tags/v2.15.306 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/.git/refs/tags/v2.15.306 2015-11-02 20:55:22.000000000 +0000 @@ -0,0 +1 @@ +2f83c4e4272ad97c704b611036efbf5aeebe1a93 diff -Nru bitshares-2-2.15.294+1027/libraries/app/impacted.cpp bitshares-2-2.15.306/libraries/app/impacted.cpp --- bitshares-2-2.15.294+1027/libraries/app/impacted.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/app/impacted.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -39,6 +39,7 @@ _impacted.insert( op.to ); } + void operator()( const asset_claim_fees_operation& op ){} void operator()( const limit_order_create_operation& op ) {} void operator()( const limit_order_cancel_operation& op ) { diff -Nru bitshares-2-2.15.294+1027/libraries/chain/account_object.cpp bitshares-2-2.15.306/libraries/chain/account_object.cpp --- bitshares-2-2.15.294+1027/libraries/chain/account_object.cpp 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/account_object.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace graphene { namespace chain { @@ -38,12 +39,32 @@ return r.to_uint64(); } -bool account_object::is_authorized_asset(const asset_object& asset_obj) const { +bool account_object::is_authorized_asset(const asset_object& asset_obj, const database& d) const +{ + if( d.head_block_time() > HARDFORK_416_TIME ) + { + if( !(asset_obj.options.flags & white_list) ) + return true; + } + for( const auto id : blacklisting_accounts ) - if( asset_obj.options.blacklist_authorities.find(id) != asset_obj.options.blacklist_authorities.end() ) return false; + { + if( asset_obj.options.blacklist_authorities.find(id) != asset_obj.options.blacklist_authorities.end() ) + return false; + } + + if( d.head_block_time() > HARDFORK_415_TIME ) + { + if( asset_obj.options.whitelist_authorities.size() == 0 ) + return true; + } for( const auto id : whitelisting_accounts ) - if( asset_obj.options.whitelist_authorities.find(id) != asset_obj.options.whitelist_authorities.end() ) return true; + { + if( asset_obj.options.whitelist_authorities.find(id) != asset_obj.options.whitelist_authorities.end() ) + return true; + } + return false; } @@ -53,7 +74,6 @@ balance += delta.amount; } - void account_statistics_object::process_fees(const account_object& a, database& d) const { if( pending_fees > 0 || pending_vested_fees > 0 ) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/asset_evaluator.cpp bitshares-2-2.15.306/libraries/chain/asset_evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/asset_evaluator.cpp 2015-10-21 19:48:07.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/asset_evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -45,20 +45,47 @@ for( auto id : op.common_options.blacklist_authorities ) d.get_object(id); - auto& asset_indx = db().get_index_type().indices().get(); + auto& asset_indx = d.get_index_type().indices().get(); auto asset_symbol_itr = asset_indx.find( op.symbol ); FC_ASSERT( asset_symbol_itr == asset_indx.end() ); - auto dotpos = op.symbol.find( '.' ); - if( dotpos != std::string::npos && d.head_block_time() > HARDFORK_385_TIME ) { - auto prefix = op.symbol.substr( 0, dotpos ); - auto asset_symbol_itr = asset_indx.find( op.symbol ); - FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered", - ("s",op.symbol)("p",prefix) ); - FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}", - ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) ); + if( d.head_block_time() > HARDFORK_385_TIME ) + { + + if( d.head_block_time() <= HARDFORK_409_TIME ) + { + auto dotpos = op.symbol.find( '.' ); + if( dotpos != std::string::npos ) + { + auto prefix = op.symbol.substr( 0, dotpos ); + auto asset_symbol_itr = asset_indx.find( op.symbol ); + FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered", + ("s",op.symbol)("p",prefix) ); + FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}", + ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) ); + } + } + else + { + auto dotpos = op.symbol.rfind( '.' ); + if( dotpos != std::string::npos ) + { + auto prefix = op.symbol.substr( 0, dotpos ); + auto asset_symbol_itr = asset_indx.find( prefix ); + FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered", + ("s",op.symbol)("p",prefix) ); + FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}", + ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) ); + } } + } + else + { + auto dotpos = op.symbol.find( '.' ); + if( dotpos != std::string::npos ) + wlog( "Asset ${s} has a name which requires hardfork 385", ("s",op.symbol) ); + } core_fee_paid -= core_fee_paid.value/2; @@ -126,7 +153,7 @@ void_result asset_issue_evaluator::do_evaluate( const asset_issue_operation& o ) { try { - database& d = db(); + const database& d = db(); const asset_object& a = o.asset_to_issue.asset_id(d); FC_ASSERT( o.issuer == a.issuer ); @@ -136,7 +163,7 @@ if( a.options.flags & white_list ) { - FC_ASSERT( to_account->is_authorized_asset( a ) ); + FC_ASSERT( to_account->is_authorized_asset( a, d ) ); } asset_dyn_data = &a.dynamic_asset_data_id(d); @@ -158,7 +185,7 @@ void_result asset_reserve_evaluator::do_evaluate( const asset_reserve_operation& o ) { try { - database& d = db(); + const database& d = db(); const asset_object& a = o.amount_to_reserve.asset_id(d); GRAPHENE_ASSERT( @@ -172,7 +199,7 @@ if( a.options.flags & white_list ) { - FC_ASSERT( from_account->is_authorized_asset( a ) ); + FC_ASSERT( from_account->is_authorized_asset( a, d ) ); } asset_dyn_data = &a.dynamic_asset_data_id(d); @@ -514,4 +541,32 @@ return void_result(); } FC_CAPTURE_AND_RETHROW((o)) } + + +void_result asset_claim_fees_evaluator::do_evaluate( const asset_claim_fees_operation& o ) +{ try { + FC_ASSERT( db().head_block_time() > HARDFORK_413_TIME ); + FC_ASSERT( o.amount_to_claim.asset_id(db()).issuer == o.issuer, "Asset fees may only be claimed by the issuer" ); + return void_result(); +} FC_CAPTURE_AND_RETHROW( (o) ) } + + +void_result asset_claim_fees_evaluator::do_apply( const asset_claim_fees_operation& o ) +{ try { + database& d = db(); + + const asset_object& a = o.amount_to_claim.asset_id(d); + const asset_dynamic_data_object& addo = a.dynamic_asset_data_id(d); + FC_ASSERT( o.amount_to_claim.amount <= addo.accumulated_fees, "Attempt to claim more fees than have accumulated", ("addo",addo) ); + + d.modify( addo, [&]( asset_dynamic_data_object& _addo ) { + _addo.accumulated_fees -= o.amount_to_claim.amount; + }); + + d.adjust_balance( o.issuer, o.amount_to_claim ); + + return void_result(); +} FC_CAPTURE_AND_RETHROW( (o) ) } + + } } // graphene::chain diff -Nru bitshares-2-2.15.294+1027/libraries/chain/confidential_evaluator.cpp bitshares-2-2.15.306/libraries/chain/confidential_evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/confidential_evaluator.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/confidential_evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -32,7 +32,7 @@ const auto& atype = o.amount.asset_id(db()); FC_ASSERT( atype.allow_confidential() ); FC_ASSERT( !atype.is_transfer_restricted() ); - FC_ASSERT( !atype.enforce_white_list() ); + FC_ASSERT( !(atype.options.flags & white_list) ); for( const auto& out : o.outputs ) { diff -Nru bitshares-2-2.15.294+1027/libraries/chain/db_init.cpp bitshares-2-2.15.306/libraries/chain/db_init.cpp --- bitshares-2-2.15.294+1027/libraries/chain/db_init.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/db_init.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -158,6 +158,7 @@ register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); } void database::initialize_indexes() diff -Nru bitshares-2-2.15.294+1027/libraries/chain/db_management.cpp bitshares-2-2.15.306/libraries/chain/db_management.cpp --- bitshares-2-2.15.294+1027/libraries/chain/db_management.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/db_management.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -144,7 +144,9 @@ { try { - while( true ) + uint32_t cutoff = get_dynamic_global_properties().last_irreversible_block_num; + + while( head_block_num() > cutoff ) { // elog("pop"); block_id_type popped_block_id = head_block_id(); diff -Nru bitshares-2-2.15.294+1027/libraries/chain/db_update.cpp bitshares-2-2.15.306/libraries/chain/db_update.cpp --- bitshares-2-2.15.294+1027/libraries/chain/db_update.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/db_update.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -366,11 +366,13 @@ void database::update_expired_feeds() { - auto& asset_idx = get_index_type().indices(); - for( const asset_object& a : asset_idx ) + auto& asset_idx = get_index_type().indices().get(); + auto itr = asset_idx.lower_bound( true /** market issued */ ); + while( itr != asset_idx.end() ) { - if( !a.is_market_issued() ) - continue; + const asset_object& a = *itr; + ++itr; + assert( a.is_market_issued() ); const asset_bitasset_data_object& b = a.bitasset_data(*this); if( b.feed_is_expired(head_block_time()) ) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/evaluator.cpp bitshares-2-2.15.306/libraries/chain/evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/evaluator.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -46,17 +47,25 @@ void generic_evaluator::prepare_fee(account_id_type account_id, asset fee) { + const database& d = db(); fee_from_account = fee; FC_ASSERT( fee.amount >= 0 ); - fee_paying_account = &account_id(db()); - fee_paying_account_statistics = &fee_paying_account->statistics(db()); + fee_paying_account = &account_id(d); + fee_paying_account_statistics = &fee_paying_account->statistics(d); - fee_asset = &fee.asset_id(db()); - fee_asset_dyn_data = &fee_asset->dynamic_asset_data_id(db()); + fee_asset = &fee.asset_id(d); + fee_asset_dyn_data = &fee_asset->dynamic_asset_data_id(d); + + if( d.head_block_time() > HARDFORK_419_TIME ) + { + FC_ASSERT( fee_paying_account->is_authorized_asset( *fee_asset, d ), "Account ${acct} '${name}' attempted to pay fee by using asset ${a} '${sym}', which is unauthorized due to whitelist / blacklist", + ("acct", fee_paying_account->id)("name", fee_paying_account->name)("a", fee_asset->id)("sym", fee_asset->symbol) ); + } if( fee_from_account.asset_id == asset_id_type() ) core_fee_paid = fee_from_account.amount; - else { + else + { asset fee_from_pool = fee_from_account * fee_asset->options.core_exchange_rate; FC_ASSERT( fee_from_pool.asset_id == asset_id_type() ); core_fee_paid = fee_from_pool.amount; diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/account_object.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/account_object.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/account_object.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/account_object.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -229,7 +229,7 @@ * @return true if this account is whitelisted and not blacklisted to transact in the provided asset; false * otherwise. */ - bool is_authorized_asset(const asset_object& asset_obj)const; + bool is_authorized_asset(const asset_object& asset_obj, const database& d)const; account_id_type get_id()const { return id; } }; diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/asset_evaluator.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/asset_evaluator.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/asset_evaluator.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/asset_evaluator.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -133,4 +133,13 @@ std::map,price_feed> median_feed_values; }; + class asset_claim_fees_evaluator : public evaluator + { + public: + typedef asset_claim_fees_operation operation_type; + + void_result do_evaluate( const asset_claim_fees_operation& o ); + void_result do_apply( const asset_claim_fees_operation& o ); + }; + } } // graphene::chain diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/asset_object.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/asset_object.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/asset_object.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/asset_object.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -82,8 +82,6 @@ /// @return true if symbol is a valid ticker symbol; false otherwise. static bool is_valid_symbol( const string& symbol ); - /// @return true if accounts must be on a whitelist in order to hold this asset; false otherwise. - bool enforce_white_list()const { return options.flags & white_list; } /// @return true if this is a market-issued asset; false otherwise. bool is_market_issued()const { return bitasset_data_id.valid(); } /// @return true if users may request force-settlement of this market-issued asset; false otherwise @@ -213,7 +211,6 @@ void update_median_feeds(time_point_sec current_time); }; - struct by_feed_expiration; typedef multi_index_container< asset_bitasset_data_object, @@ -227,17 +224,19 @@ typedef flat_index asset_bitasset_data_index; struct by_symbol; + struct by_type; typedef multi_index_container< asset_object, indexed_by< ordered_unique< tag, member< object, object_id_type, &object::id > >, - ordered_unique< tag, member > + ordered_unique< tag, member >, + ordered_non_unique< tag, const_mem_fun > > > asset_object_multi_index_type; typedef generic_index asset_index; - } } // graphene::chain + FC_REFLECT_DERIVED( graphene::chain::asset_dynamic_data_object, (graphene::db::object), (current_supply)(confidential_supply)(accumulated_fees)(fee_pool) ) @@ -260,4 +259,3 @@ (dynamic_asset_data_id) (bitasset_data_id) ) - diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/config.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/config.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/config.hpp 2015-10-21 19:48:07.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/config.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -140,7 +140,7 @@ #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 -#define GRAPHENE_CURRENT_DB_VERSION "BTS2.2" +#define GRAPHENE_CURRENT_DB_VERSION "BTS2.3" #define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/global_property_object.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/global_property_object.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/global_property_object.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/global_property_object.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -128,6 +128,7 @@ (time) (current_witness) (next_maintenance_time) + (last_budget_time) (witness_budget) (accounts_registered_this_interval) (recently_missed_count) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/hardfork.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/hardfork.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/hardfork.hpp 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/hardfork.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -24,3 +24,8 @@ #define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 )) #define HARDFORK_385_TIME (fc::time_point_sec( 1445558400 )) // October 23 enforce PARENT.CHILD and allow short names #define HARDFORK_393_TIME (fc::time_point_sec( 2445558400 )) // Refund order creation fee on cancel +#define HARDFORK_409_TIME (fc::time_point_sec( 1446652800 )) +#define HARDFORK_413_TIME (fc::time_point_sec( 1446652800 )) +#define HARDFORK_415_TIME (fc::time_point_sec( 1446652800 )) +#define HARDFORK_416_TIME (fc::time_point_sec( 1446652800 )) +#define HARDFORK_419_TIME (fc::time_point_sec( 1446652800 )) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -53,12 +53,11 @@ /// the core exchange rate. price core_exchange_rate; - /// A set of accounts which maintain whitelists to consult for this asset. If enforce_white_list() returns - /// true, an account may only send, receive, trade, etc. in this asset if one of these accounts appears in - /// its account_object::whitelisting_accounts field. + /// A set of accounts which maintain whitelists to consult for this asset. If whitelist_authorities + /// is non-empty, then only accounts in whitelist_authorities are allowed to hold, use, or transfer the asset. flat_set whitelist_authorities; - /// A set of accounts which maintain blacklists to consult for this asset. If enforce_white_list() returns - /// true, an account may only send, receive, trade, etc. in this asset if none of these accounts appears in + /// A set of accounts which maintain blacklists to consult for this asset. If flags & white_list is set, + /// an account may only send, receive, trade, etc. in this asset if none of these accounts appears in /// its account_object::blacklisting_accounts field. If the account is blacklisted, it may not transact in /// this asset even if it is also whitelisted. flat_set blacklist_authorities; @@ -420,8 +419,30 @@ void validate()const; }; + /** + * @brief used to transfer accumulated fees back to the issuer's balance. + */ + struct asset_claim_fees_operation : public base_operation + { + struct fee_parameters_type { + uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; + }; + + asset fee; + account_id_type issuer; + asset amount_to_claim; /// amount_to_claim.asset_id->issuer must == issuer + extensions_type extensions; + + account_id_type fee_payer()const { return issuer; } + void validate()const; + }; + + } } // graphene::chain +FC_REFLECT( graphene::chain::asset_claim_fees_operation, (fee)(issuer)(amount_to_claim)(extensions) ) +FC_REFLECT( graphene::chain::asset_claim_fees_operation::fee_parameters_type, (fee) ) + FC_REFLECT( graphene::chain::asset_options, (max_supply) (market_fee_percent) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/base.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/base.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/base.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/base.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -117,4 +117,5 @@ } } // graphene::chain FC_REFLECT_TYPENAME( graphene::chain::operation_result ) +FC_REFLECT_TYPENAME( graphene::chain::future_extensions ) FC_REFLECT( graphene::chain::void_result, ) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/operations.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/operations.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/operations.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/operations.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -85,8 +85,8 @@ transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, - - asset_settle_cancel_operation // VIRTUAL + asset_settle_cancel_operation, // VIRTUAL + asset_claim_fees_operation > operation; /// @} // operations group diff -Nru bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/types.hpp bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/types.hpp --- bitshares-2-2.15.294+1027/libraries/chain/include/graphene/chain/protocol/types.hpp 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/include/graphene/chain/protocol/types.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -310,6 +310,7 @@ FC_REFLECT_TYPENAME( graphene::chain::withdraw_permission_id_type ) FC_REFLECT_TYPENAME( graphene::chain::vesting_balance_id_type ) FC_REFLECT_TYPENAME( graphene::chain::worker_id_type ) +FC_REFLECT_TYPENAME( graphene::chain::balance_id_type ) FC_REFLECT_TYPENAME( graphene::chain::global_property_id_type ) FC_REFLECT_TYPENAME( graphene::chain::dynamic_global_property_id_type ) FC_REFLECT_TYPENAME( graphene::chain::asset_dynamic_data_id_type ) diff -Nru bitshares-2-2.15.294+1027/libraries/chain/market_evaluator.cpp bitshares-2-2.15.306/libraries/chain/market_evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/market_evaluator.cpp 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/market_evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -29,7 +29,7 @@ namespace graphene { namespace chain { void_result limit_order_create_evaluator::do_evaluate(const limit_order_create_operation& op) { try { - database& d = db(); + const database& d = db(); FC_ASSERT( op.expiration >= d.head_block_time() ); @@ -42,8 +42,16 @@ if( _sell_asset->options.blacklist_markets.size() ) FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) == _sell_asset->options.blacklist_markets.end() ); - if( _sell_asset->enforce_white_list() ) FC_ASSERT( _seller->is_authorized_asset( *_sell_asset ) ); - if( _receive_asset->enforce_white_list() ) FC_ASSERT( _seller->is_authorized_asset( *_receive_asset ) ); + if( d.head_block_time() <= HARDFORK_416_TIME ) + { + if( _sell_asset->options.flags & white_list ) FC_ASSERT( _seller->is_authorized_asset( *_sell_asset, d ) ); + if( _receive_asset->options.flags & white_list ) FC_ASSERT( _seller->is_authorized_asset( *_receive_asset, d ) ); + } + else + { + FC_ASSERT( _seller->is_authorized_asset( *_sell_asset, d ) ); + FC_ASSERT( _seller->is_authorized_asset( *_receive_asset, d ) ); + } FC_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell, "insufficient balance", ("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) ); diff -Nru bitshares-2-2.15.294+1027/libraries/chain/protocol/asset_ops.cpp bitshares-2-2.15.306/libraries/chain/protocol/asset_ops.cpp --- bitshares-2-2.15.294+1027/libraries/chain/protocol/asset_ops.cpp 2015-10-21 19:48:06.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/protocol/asset_ops.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -227,4 +227,9 @@ } } +void asset_claim_fees_operation::validate()const { + FC_ASSERT( fee.amount >= 0 ); + FC_ASSERT( amount_to_claim.amount > 0 ); +} + } } // namespace graphene::chain diff -Nru bitshares-2-2.15.294+1027/libraries/chain/transfer_evaluator.cpp bitshares-2-2.15.306/libraries/chain/transfer_evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/transfer_evaluator.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/transfer_evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -21,12 +21,13 @@ #include #include #include +#include namespace graphene { namespace chain { void_result transfer_evaluator::do_evaluate( const transfer_operation& op ) { try { - database& d = db(); + const database& d = db(); const account_object& from_account = op.from(d); const account_object& to_account = op.to(d); @@ -38,14 +39,14 @@ if( asset_type.options.flags & white_list ) { GRAPHENE_ASSERT( - from_account.is_authorized_asset( asset_type ), + from_account.is_authorized_asset( asset_type, d ), transfer_from_account_not_whitelisted, "'from' account ${from} is not whitelisted for asset ${asset}", ("from",op.from) ("asset",op.amount.asset_id) ); GRAPHENE_ASSERT( - to_account.is_authorized_asset( asset_type ), + to_account.is_authorized_asset( asset_type, d ), transfer_to_account_not_whitelisted, "'to' account ${to} is not whitelisted for asset ${asset}", ("to",op.to) @@ -53,8 +54,12 @@ ); } - if( fee_asset_type.options.flags & white_list ) - FC_ASSERT( from_account.is_authorized_asset( asset_type ) ); + if( d.head_block_time() <= HARDFORK_419_TIME ) + { + if( fee_asset_type.options.flags & white_list ) + FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) ); + } + // the above becomes no-op after hardfork because this check will then be performed in evaluator if( asset_type.is_transfer_restricted() ) { @@ -87,7 +92,7 @@ void_result override_transfer_evaluator::do_evaluate( const override_transfer_operation& op ) { try { - database& d = db(); + const database& d = db(); const asset_object& asset_type = op.amount.asset_id(d); GRAPHENE_ASSERT( @@ -104,12 +109,16 @@ if( asset_type.options.flags & white_list ) { - FC_ASSERT( to_account.is_authorized_asset( asset_type ) ); - FC_ASSERT( from_account.is_authorized_asset( asset_type ) ); + FC_ASSERT( to_account.is_authorized_asset( asset_type, d ) ); + FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) ); } - if( fee_asset_type.options.flags & white_list ) - FC_ASSERT( from_account.is_authorized_asset( asset_type ) ); + if( d.head_block_time() <= HARDFORK_419_TIME ) + { + if( fee_asset_type.options.flags & white_list ) + FC_ASSERT( from_account.is_authorized_asset( asset_type, d ) ); + } + // the above becomes no-op after hardfork because this check will then be performed in evaluator FC_ASSERT( d.get_balance( from_account, asset_type ).amount >= op.amount.amount, "", ("total_transfer",op.amount)("balance",d.get_balance(from_account, asset_type).amount) ); diff -Nru bitshares-2-2.15.294+1027/libraries/chain/vesting_balance_object.cpp bitshares-2-2.15.306/libraries/chain/vesting_balance_object.cpp --- bitshares-2-2.15.294+1027/libraries/chain/vesting_balance_object.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/vesting_balance_object.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -94,7 +94,7 @@ delta_coin_seconds *= delta_seconds; fc::uint128_t coin_seconds_earned_cap = ctx.balance.amount.value; - coin_seconds_earned_cap *= vesting_seconds; + coin_seconds_earned_cap *= std::max(vesting_seconds, 1u); return std::min(coin_seconds_earned + delta_coin_seconds, coin_seconds_earned_cap); } @@ -110,7 +110,7 @@ if(ctx.now <= start_claim) return asset(0, ctx.balance.asset_id); fc::uint128_t cs_earned = compute_coin_seconds_earned(ctx); - fc::uint128_t withdraw_available = cs_earned / vesting_seconds; + fc::uint128_t withdraw_available = cs_earned / std::max(vesting_seconds, 1u); assert(withdraw_available <= ctx.balance.amount.value); return asset(withdraw_available.to_uint64(), ctx.balance.asset_id); } @@ -123,14 +123,14 @@ void cdd_vesting_policy::on_deposit_vested(const vesting_policy_context& ctx) { on_deposit(ctx); - coin_seconds_earned += ctx.amount.amount.value * vesting_seconds; + coin_seconds_earned += ctx.amount.amount.value * std::max(vesting_seconds, 1u); } void cdd_vesting_policy::on_withdraw(const vesting_policy_context& ctx) { update_coin_seconds_earned(ctx); fc::uint128_t coin_seconds_needed = ctx.amount.amount.value; - coin_seconds_needed *= vesting_seconds; + coin_seconds_needed *= std::max(vesting_seconds, 1u); // is_withdraw_allowed should forbid any withdrawal that // would trigger this assert assert(coin_seconds_needed <= coin_seconds_earned); diff -Nru bitshares-2-2.15.294+1027/libraries/chain/withdraw_permission_evaluator.cpp bitshares-2-2.15.306/libraries/chain/withdraw_permission_evaluator.cpp --- bitshares-2-2.15.294+1027/libraries/chain/withdraw_permission_evaluator.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/chain/withdraw_permission_evaluator.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include namespace graphene { namespace chain { @@ -53,7 +54,7 @@ void_result withdraw_permission_claim_evaluator::do_evaluate(const withdraw_permission_claim_evaluator::operation_type& op) { try { - database& d = db(); + const database& d = db(); const withdraw_permission_object& permit = op.withdraw_permission(d); FC_ASSERT(permit.expiration > d.head_block_time() ); @@ -65,12 +66,22 @@ const asset_object& _asset = op.amount_to_withdraw.asset_id(d); if( _asset.is_transfer_restricted() ) FC_ASSERT( _asset.issuer == permit.authorized_account || _asset.issuer == permit.withdraw_from_account ); - if( _asset.enforce_white_list() ) + if( d.head_block_time() <= HARDFORK_416_TIME ) + { + if( _asset.options.flags & white_list ) + { + const account_object& from = op.withdraw_to_account(d); + const account_object& to = permit.authorized_account(d); + FC_ASSERT( to.is_authorized_asset( _asset, d ) ); + FC_ASSERT( from.is_authorized_asset( _asset, d ) ); + } + } + else { const account_object& from = op.withdraw_to_account(d); const account_object& to = permit.authorized_account(d); - FC_ASSERT( to.is_authorized_asset( _asset ) ); - FC_ASSERT( from.is_authorized_asset( _asset ) ); + FC_ASSERT( to.is_authorized_asset( _asset, d ) ); + FC_ASSERT( from.is_authorized_asset( _asset, d ) ); } return void_result(); diff -Nru bitshares-2-2.15.294+1027/libraries/db/include/graphene/db/generic_index.hpp bitshares-2-2.15.306/libraries/db/include/graphene/db/generic_index.hpp --- bitshares-2-2.15.294+1027/libraries/db/include/graphene/db/generic_index.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/db/include/graphene/db/generic_index.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -23,7 +23,6 @@ #include #include #include -#include #include namespace graphene { namespace chain { @@ -117,7 +116,7 @@ struct sparse_index : public generic_index, member > diff -Nru bitshares-2-2.15.294+1027/libraries/fc/include/fc/io/raw.hpp bitshares-2-2.15.306/libraries/fc/include/fc/io/raw.hpp --- bitshares-2-2.15.294+1027/libraries/fc/include/fc/io/raw.hpp 2015-10-20 19:59:53.000000000 +0000 +++ bitshares-2-2.15.306/libraries/fc/include/fc/io/raw.hpp 2015-11-02 20:55:24.000000000 +0000 @@ -236,7 +236,13 @@ // bool template inline void pack( Stream& s, const bool& v ) { pack( s, uint8_t(v) ); } - template inline void unpack( Stream& s, bool& v ) { uint8_t b; unpack( s, b ); v=(b!=0); } + template inline void unpack( Stream& s, bool& v ) + { + uint8_t b; + unpack( s, b ); + FC_ASSERT( (b & ~1) == 0 ); + v=(b!=0); + } namespace detail { diff -Nru bitshares-2-2.15.294+1027/libraries/plugins/witness/witness.cpp bitshares-2-2.15.306/libraries/plugins/witness/witness.cpp --- bitshares-2-2.15.294+1027/libraries/plugins/witness/witness.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/libraries/plugins/witness/witness.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -146,12 +146,18 @@ void witness_plugin::schedule_production_loop() { //Schedule for the next second's tick regardless of chain state - // If we would wait less than 200ms, wait for the whole second. - fc::time_point now = graphene::time::now(); - fc::time_point_sec next_second( now + fc::microseconds( 1200000 ) ); - //wdump( (now.time_since_epoch().count())(next_second) ); + // If we would wait less than 50ms, wait for the whole second. + fc::time_point ntp_now = graphene::time::now(); + fc::time_point fc_now = fc::time_point::now(); + int64_t time_to_next_second = 1000000 - (ntp_now.time_since_epoch().count() % 1000000); + if( time_to_next_second < 50000 ) // we must sleep for at least 50ms + time_to_next_second += 1000000; + + fc::time_point next_wakeup( fc_now + fc::microseconds( time_to_next_second ) ); + + //wdump( (now.time_since_epoch().count())(next_wakeup.time_since_epoch().count()) ); _block_production_task = fc::schedule([this]{block_production_loop();}, - next_second, "Witness Block Production"); + next_wakeup, "Witness Block Production"); } block_production_condition::block_production_condition_enum witness_plugin::block_production_loop() diff -Nru bitshares-2-2.15.294+1027/libraries/wallet/wallet.cpp bitshares-2-2.15.306/libraries/wallet/wallet.cpp --- bitshares-2-2.15.294+1027/libraries/wallet/wallet.cpp 2015-10-28 14:18:43.000000000 +0000 +++ bitshares-2-2.15.306/libraries/wallet/wallet.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -2955,7 +2955,7 @@ string symbol, bool broadcast /* = false */) { - return my->fund_asset_fee_pool(from, amount, symbol, broadcast); + return my->reserve_asset(from, amount, symbol, broadcast); } signed_transaction wallet_api::global_settle_asset(string symbol, diff -Nru bitshares-2-2.15.294+1027/programs/genesis_util/apply_patch.py bitshares-2-2.15.306/programs/genesis_util/apply_patch.py --- bitshares-2-2.15.294+1027/programs/genesis_util/apply_patch.py 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/programs/genesis_util/apply_patch.py 2015-11-02 20:55:23.000000000 +0000 @@ -31,6 +31,9 @@ with open(filename, "r") as f: patch = json.load(f) for k, v in patch.get("append", {}).items(): + if k not in genesis: + genesis[k] = [] + sys.stderr.write("[WARN] item {k} was created\n".format(k=k)) genesis[k].extend(v) sys.stderr.write("appended {n} items to {k}\n".format(n=len(v), k=k)) for k, v in patch.get("replace", {}).items(): diff -Nru bitshares-2-2.15.294+1027/programs/genesis_util/generate_init_config.py bitshares-2-2.15.306/programs/genesis_util/generate_init_config.py --- bitshares-2-2.15.294+1027/programs/genesis_util/generate_init_config.py 1970-01-01 00:00:00.000000000 +0000 +++ bitshares-2-2.15.306/programs/genesis_util/generate_init_config.py 2015-11-02 20:55:23.000000000 +0000 @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +import argparse +import json +import subprocess +import sys + +def dump_json(obj, out, pretty): + if pretty: + json.dump(obj, out, indent=2, sort_keys=True) + else: + json.dump(obj, out, separators=(",", ":"), sort_keys=True) + return + +def main(): + parser = argparse.ArgumentParser(description="Generate a patch file that adds init accounts") + parser.add_argument("-o", "--output", metavar="OUT", default="-", help="output filename (default: stdout)") + parser.add_argument("-n", "--num", metavar="N", default=11, type=int, help="number of init witnesses") + parser.add_argument("-w", "--witness", metavar="N", default=1, type=int, help="starting witness ID") + parser.add_argument("-p", "--pretty", action="store_true", default=False, help="pretty print output") + parser.add_argument("-m", "--mname", metavar="HOSTNAME", default="", help="machine name of target machine") + parser.add_argument("-s", "--secret", metavar="SECRET", default=None, help="private key generation secret") + opts = parser.parse_args() + + if opts.secret is None: + sys.stderr.write("missing required parameter --secret\n") + sys.stderr.flush() + sys.exit(1) + + out_wits = [] + out_keys = [] + + for i in range(opts.num): + if opts.mname != "": + istr = "wit-block-signing-"+opts.mname+"-"+str(i) + else: + istr = "wit-block-signing-"+str(i) + prod_str = subprocess.check_output(["programs/genesis_util/get_dev_key", opts.secret, istr]).decode("utf-8") + prod = json.loads(prod_str) + out_wits.append('witness-id = "1.6.'+str(opts.witness+i)+'"\n') + out_keys.append("private-key = "+json.dumps([prod[0]["public_key"], prod[0]["private_key"]])+"\n") + + out_data = "".join(out_wits + ["\n"] + out_keys) + + if opts.output == "-": + sys.stdout.write(out_data) + sys.stdout.flush() + else: + with open(opts.output, "w") as f: + f.write(out_data) + return + +if __name__ == "__main__": + main() diff -Nru bitshares-2-2.15.294+1027/tests/common/database_fixture.cpp bitshares-2-2.15.306/tests/common/database_fixture.cpp --- bitshares-2-2.15.294+1027/tests/common/database_fixture.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/common/database_fixture.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -46,6 +46,8 @@ using namespace graphene::chain::test; +uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP = 1431700000; + namespace graphene { namespace chain { using std::cout; @@ -499,7 +501,9 @@ creator.common_options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY; creator.common_options.flags = flags; creator.common_options.issuer_permissions = flags; + trx.operations.clear(); trx.operations.push_back(std::move(creator)); + set_expiration( db, trx ); trx.validate(); processed_transaction ptx = db.push_transaction(trx, ~0); trx.operations.clear(); @@ -733,6 +737,8 @@ op.publisher = by.id; op.asset_id = mia.id; op.feed = f; + if( op.feed.core_exchange_rate.is_null() ) + op.feed.core_exchange_rate = op.feed.settlement_price; trx.operations.emplace_back( std::move(op) ); for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); diff -Nru bitshares-2-2.15.294+1027/tests/common/database_fixture.hpp bitshares-2-2.15.306/tests/common/database_fixture.hpp --- bitshares-2-2.15.294+1027/tests/common/database_fixture.hpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/common/database_fixture.hpp 2015-11-02 20:55:23.000000000 +0000 @@ -29,7 +29,7 @@ using namespace graphene::db; -#define GRAPHENE_TESTING_GENESIS_TIMESTAMP (1431700000) +extern uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP; #define PUSH_TX \ graphene::chain::test::_push_transaction diff -Nru bitshares-2-2.15.294+1027/tests/tests/block_tests.cpp bitshares-2-2.15.306/tests/tests/block_tests.cpp --- bitshares-2-2.15.294+1027/tests/tests/block_tests.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/block_tests.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -131,14 +131,15 @@ // TODO: Don't generate this here auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); - signed_block b200; + signed_block cutoff_block; { database db; db.open(data_dir.path(), make_genesis ); b = db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + // TODO: Change this test when we correct #406 // n.b. we generate GRAPHENE_MIN_UNDO_HISTORY+1 extra blocks which will be discarded on save - for( uint32_t i = 1; i < 200+GRAPHENE_MIN_UNDO_HISTORY+1; ++i ) + for( uint32_t i = 1; ; ++i ) { BOOST_CHECK( db.head_block_id() == b.id() ); //witness_id_type prev_witness = b.witness; @@ -146,16 +147,20 @@ //BOOST_CHECK( cur_witness != prev_witness ); b = db.generate_block(db.get_slot_time(1), cur_witness, init_account_priv_key, database::skip_nothing); BOOST_CHECK( b.witness == cur_witness ); - if( i == 199 ) - b200 = b; + uint32_t cutoff_height = db.get_dynamic_global_properties().last_irreversible_block_num; + if( cutoff_height >= 200 ) + { + cutoff_block = *(db.fetch_block_by_number( cutoff_height )); + break; + } } db.close(); } { database db; db.open(data_dir.path(), []{return genesis_state_type();}); - BOOST_CHECK_EQUAL( db.head_block_num(), 200 ); - b = b200; + BOOST_CHECK_EQUAL( db.head_block_num(), cutoff_block.block_num() ); + b = cutoff_block; for( uint32_t i = 0; i < 200; ++i ) { BOOST_CHECK( db.head_block_id() == b.id() ); @@ -164,7 +169,7 @@ //BOOST_CHECK( cur_witness != prev_witness ); b = db.generate_block(db.get_slot_time(1), cur_witness, init_account_priv_key, database::skip_nothing); } - BOOST_CHECK_EQUAL( db.head_block_num(), 400 ); + BOOST_CHECK_EQUAL( db.head_block_num(), cutoff_block.block_num()+200 ); } } catch (fc::exception& e) { edump((e.to_detail_string())); diff -Nru bitshares-2-2.15.294+1027/tests/tests/fee_tests.cpp bitshares-2-2.15.306/tests/tests/fee_tests.cpp --- bitshares-2-2.15.294+1027/tests/tests/fee_tests.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/fee_tests.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -67,6 +68,138 @@ } } +BOOST_AUTO_TEST_CASE(asset_claim_fees_test) +{ + try + { + ACTORS((alice)(bob)(izzy)(jill)); + // Izzy issues asset to Alice + // Jill issues asset to Bob + // Alice and Bob trade in the market and pay fees + // Verify that Izzy and Jill can claim the fees + + const share_type core_prec = asset::scaled_precision( asset_id_type()(db).precision ); + + // Return number of core shares (times precision) + auto _core = [&]( int64_t x ) -> asset + { return asset( x*core_prec ); }; + + transfer( committee_account, alice_id, _core(1000000) ); + transfer( committee_account, bob_id, _core(1000000) ); + transfer( committee_account, izzy_id, _core(1000000) ); + transfer( committee_account, jill_id, _core(1000000) ); + + asset_id_type izzycoin_id = create_bitasset( "IZZYCOIN", izzy_id, GRAPHENE_1_PERCENT, charge_market_fee ).id; + asset_id_type jillcoin_id = create_bitasset( "JILLCOIN", jill_id, 2*GRAPHENE_1_PERCENT, charge_market_fee ).id; + + const share_type izzy_prec = asset::scaled_precision( asset_id_type(izzycoin_id)(db).precision ); + const share_type jill_prec = asset::scaled_precision( asset_id_type(jillcoin_id)(db).precision ); + + auto _izzy = [&]( int64_t x ) -> asset + { return asset( x*izzy_prec, izzycoin_id ); }; + auto _jill = [&]( int64_t x ) -> asset + { return asset( x*jill_prec, jillcoin_id ); }; + + update_feed_producers( izzycoin_id(db), { izzy_id } ); + update_feed_producers( jillcoin_id(db), { jill_id } ); + + const asset izzy_satoshi = asset(1, izzycoin_id); + const asset jill_satoshi = asset(1, jillcoin_id); + + // Izzycoin is worth 100 BTS + price_feed feed; + feed.settlement_price = price( _izzy(1), _core(100) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 150 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( izzycoin_id(db), izzy, feed ); + + // Jillcoin is worth 30 BTS + feed.settlement_price = price( _jill(1), _core(30) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 150 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( jillcoin_id(db), jill, feed ); + + enable_fees(); + + // Alice and Bob create some coins + borrow( alice_id, _izzy( 200), _core( 60000) ); + borrow( bob_id, _jill(2000), _core(180000) ); + + // Alice and Bob place orders which match + create_sell_order( alice_id, _izzy(100), _jill(300) ); // Alice is willing to sell her Izzy's for 3 Jill + create_sell_order( bob_id, _jill(700), _izzy(200) ); // Bob is buying up to 200 Izzy's for up to 3.5 Jill + + // 100 Izzys and 300 Jills are matched, so the fees should be + // 1 Izzy (1%) and 6 Jill (2%). + + auto claim_fees = [&]( account_id_type issuer, asset amount_to_claim ) + { + asset_claim_fees_operation claim_op; + claim_op.issuer = issuer; + claim_op.amount_to_claim = amount_to_claim; + signed_transaction tx; + tx.operations.push_back( claim_op ); + db.current_fee_schedule().set_fee( tx.operations.back() ); + set_expiration( db, tx ); + fc::ecc::private_key my_pk = (issuer == izzy_id) ? izzy_private_key : jill_private_key; + fc::ecc::private_key your_pk = (issuer == izzy_id) ? jill_private_key : izzy_private_key; + sign( tx, your_pk ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx ), fc::exception ); + tx.signatures.clear(); + sign( tx, my_pk ); + PUSH_TX( db, tx ); + }; + + { + const asset_object& izzycoin = izzycoin_id(db); + const asset_object& jillcoin = jillcoin_id(db); + + //wdump( (izzycoin)(izzycoin.dynamic_asset_data_id(db))((*izzycoin.bitasset_data_id)(db)) ); + //wdump( (jillcoin)(jillcoin.dynamic_asset_data_id(db))((*jillcoin.bitasset_data_id)(db)) ); + + // check the correct amount of fees has been awarded + BOOST_CHECK( izzycoin.dynamic_asset_data_id(db).accumulated_fees == _izzy(1).amount ); + BOOST_CHECK( jillcoin.dynamic_asset_data_id(db).accumulated_fees == _jill(6).amount ); + + } + + { + // can't claim before hardfork + GRAPHENE_REQUIRE_THROW( claim_fees( izzy_id, _izzy(1) ), fc::exception ); + generate_blocks( HARDFORK_413_TIME ); + while( db.head_block_time() <= HARDFORK_413_TIME ) + { + generate_block(); + } + } + + { + const asset_object& izzycoin = izzycoin_id(db); + const asset_object& jillcoin = jillcoin_id(db); + + // can't claim more than balance + GRAPHENE_REQUIRE_THROW( claim_fees( izzy_id, _izzy(1) + izzy_satoshi ), fc::exception ); + GRAPHENE_REQUIRE_THROW( claim_fees( jill_id, _jill(6) + jill_satoshi ), fc::exception ); + + // can't claim asset that doesn't belong to you + GRAPHENE_REQUIRE_THROW( claim_fees( jill_id, izzy_satoshi ), fc::exception ); + GRAPHENE_REQUIRE_THROW( claim_fees( izzy_id, jill_satoshi ), fc::exception ); + + // can claim asset in one go + claim_fees( izzy_id, _izzy(1) ); + GRAPHENE_REQUIRE_THROW( claim_fees( izzy_id, izzy_satoshi ), fc::exception ); + BOOST_CHECK( izzycoin.dynamic_asset_data_id(db).accumulated_fees == _izzy(0).amount ); + + // can claim in multiple goes + claim_fees( jill_id, _jill(4) ); + BOOST_CHECK( jillcoin.dynamic_asset_data_id(db).accumulated_fees == _jill(2).amount ); + GRAPHENE_REQUIRE_THROW( claim_fees( jill_id, _jill(2) + jill_satoshi ), fc::exception ); + claim_fees( jill_id, _jill(2) ); + BOOST_CHECK( jillcoin.dynamic_asset_data_id(db).accumulated_fees == _jill(0).amount ); + } + } + FC_LOG_AND_RETHROW() +} /////////////////////////////////////////////////////////////// // cashback_test infrastructure // diff -Nru bitshares-2-2.15.294+1027/tests/tests/main.cpp bitshares-2-2.15.306/tests/tests/main.cpp --- bitshares-2-2.15.294+1027/tests/tests/main.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/main.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -23,8 +23,16 @@ #include #include +extern uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP; + boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { std::srand(time(NULL)); std::cout << "Random number generator seeded to " << time(NULL) << std::endl; + const char* genesis_timestamp_str = getenv("GRAPHENE_TESTING_GENESIS_TIMESTAMP"); + if( genesis_timestamp_str != nullptr ) + { + GRAPHENE_TESTING_GENESIS_TIMESTAMP = std::stoul( genesis_timestamp_str ); + } + std::cout << "GRAPHENE_TESTING_GENESIS_TIMESTAMP is " << GRAPHENE_TESTING_GENESIS_TIMESTAMP << std::endl; return nullptr; } diff -Nru bitshares-2-2.15.294+1027/tests/tests/operation_tests2.cpp bitshares-2-2.15.306/tests/tests/operation_tests2.cpp --- bitshares-2-2.15.294+1027/tests/tests/operation_tests2.cpp 2015-10-21 19:48:07.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/operation_tests2.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -348,7 +349,8 @@ asset_publish_feed_operation op; op.publisher = vikram_id; op.asset_id = bit_usd_id; - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30)); + // We'll expire margins after a month // Accept defaults for required collateral trx.operations.emplace_back(op); @@ -359,7 +361,7 @@ BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO); op.publisher = ben_id; - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25)); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); @@ -367,7 +369,7 @@ BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO); op.publisher = dan_id; - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40)); op.feed.maximum_short_squeeze_ratio = 1001; op.feed.maintenance_collateral_ratio = 1001; trx.operations.back() = op; @@ -452,15 +454,16 @@ generate_block(); int produced = 0; - // Make sure we get scheduled exactly once in witnesses.size() blocks + // Make sure we get scheduled at least once in witnesses.size()*2 blocks + // may take this many unless we measure where in the scheduling round we are // TODO: intense_test that repeats this loop many times - for( size_t i=0; i(); + check_vesting_1b( vbid ); + } + + // This block creates a zero-second VBO with a worker_create_operation. + { + worker_create_operation create_op; + create_op.owner = alice_id; + create_op.work_begin_date = db.head_block_time(); + create_op.work_end_date = db.head_block_time() + fc::days(1000); + create_op.daily_pay = share_type( 10000 ); + create_op.name = "alice"; + create_op.url = ""; + create_op.initializer = vesting_balance_worker_initializer(0); + signed_transaction create_tx; + create_tx.operations.push_back(create_op); + set_expiration( db, create_tx ); + sign(create_tx, alice_private_key); + processed_transaction ptx = PUSH_TX( db, create_tx ); + worker_id_type wid = ptx.operation_results[0].get(); + + // vote it in + account_update_operation vote_op; + vote_op.account = alice_id; + vote_op.new_options = alice_id(db).options; + vote_op.new_options->votes.insert(wid(db).vote_for); + signed_transaction vote_tx; + vote_tx.operations.push_back(vote_op); + set_expiration( db, vote_tx ); + sign( vote_tx, alice_private_key ); + PUSH_TX( db, vote_tx ); + + // vote it in, wait for one maint. for vote to take effect + vesting_balance_id_type vbid = wid(db).worker.get().balance; + generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); + generate_block(); + // wait for another maint. for worker to be paid + generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); + BOOST_CHECK( vbid(db).get_allowed_withdraw(db.head_block_time()) == asset(0) ); + generate_block(); + BOOST_CHECK( vbid(db).get_allowed_withdraw(db.head_block_time()) == asset(10000) ); + + /* + db.get_index_type< simple_index >().inspect_all_objects( + [&](const object& o) + { + ilog( "budget: ${brec}", ("brec", static_cast(o)) ); + }); + */ + } + } FC_LOG_AND_RETHROW() +} + // TODO: Write linear VBO tests BOOST_AUTO_TEST_SUITE_END() diff -Nru bitshares-2-2.15.294+1027/tests/tests/operation_tests.cpp bitshares-2-2.15.306/tests/tests/operation_tests.cpp --- bitshares-2-2.15.294+1027/tests/tests/operation_tests.cpp 2015-10-21 19:48:07.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/operation_tests.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -636,11 +636,11 @@ pop.asset_id = bit_usd.get_id(); pop.publisher = get_account("init0").get_id(); price_feed feed; - feed.settlement_price = price(bit_usd.amount(5), bit_usd.amount(5)); + feed.settlement_price = feed.core_exchange_rate = price(bit_usd.amount(5), bit_usd.amount(5)); REQUIRE_THROW_WITH_VALUE(pop, feed, feed); - feed.settlement_price = ~price(bit_usd.amount(5), asset(5)); + feed.settlement_price = feed.core_exchange_rate = ~price(bit_usd.amount(5), asset(5)); REQUIRE_THROW_WITH_VALUE(pop, feed, feed); - feed.settlement_price = price(bit_usd.amount(5), asset(5)); + feed.settlement_price = feed.core_exchange_rate = price(bit_usd.amount(5), asset(5)); pop.feed = feed; REQUIRE_THROW_WITH_VALUE(pop, feed.maintenance_collateral_ratio, 0); trx.operations.back() = pop; @@ -687,7 +687,7 @@ const asset_object& test_asset = test_asset_id(db); BOOST_CHECK(test_asset.symbol == "TEST"); BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2)); - BOOST_CHECK(!test_asset.enforce_white_list()); + BOOST_CHECK((test_asset.options.flags & white_list) == 0); BOOST_CHECK(test_asset.options.max_supply == 100000000); BOOST_CHECK(!test_asset.bitasset_data_id.valid()); BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100); @@ -1144,7 +1144,7 @@ asset_publish_feed_operation op; op.publisher = active_witnesses[0]; op.asset_id = bit_usd.get_id(); - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30)); // Accept defaults for required collateral trx.operations.emplace_back(op); PUSH_TX( db, trx, ~0 ); @@ -1154,7 +1154,7 @@ BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO); op.publisher = active_witnesses[1]; - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25)); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); @@ -1162,7 +1162,7 @@ BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO); op.publisher = active_witnesses[2]; - op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40)); + op.feed.settlement_price = op.feed.core_exchange_rate = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40)); // But this witness is an idiot. op.feed.maintenance_collateral_ratio = 1001; trx.operations.back() = op; diff -Nru bitshares-2-2.15.294+1027/tests/tests/uia_tests.cpp bitshares-2-2.15.306/tests/tests/uia_tests.cpp --- bitshares-2-2.15.294+1027/tests/tests/uia_tests.cpp 2015-10-20 19:59:36.000000000 +0000 +++ bitshares-2-2.15.306/tests/tests/uia_tests.cpp 2015-11-02 20:55:23.000000000 +0000 @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -57,7 +58,7 @@ const asset_object& test_asset = test_asset_id(db); BOOST_CHECK(test_asset.symbol == "ADVANCED"); BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2)); - BOOST_CHECK(test_asset.enforce_white_list()); + BOOST_CHECK(test_asset.options.flags & white_list); BOOST_CHECK(test_asset.options.max_supply == 100000000); BOOST_CHECK(!test_asset.bitasset_data_id.valid()); BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100); @@ -134,33 +135,75 @@ BOOST_AUTO_TEST_CASE( issue_whitelist_uia ) { try { - INVOKE(create_advanced_uia); - const asset_object& advanced = get_asset("ADVANCED"); - const account_object& nathan = create_account("nathan"); - upgrade_to_lifetime_member(nathan); + account_id_type izzy_id = create_account("izzy").id; + const asset_id_type uia_id = create_user_issued_asset( + "ADVANCED", izzy_id(db), white_list ).id; + account_id_type nathan_id = create_account("nathan").id; + account_id_type vikram_id = create_account("vikram").id; trx.clear(); asset_issue_operation op; - op.issuer = advanced.issuer; - op.asset_to_issue = advanced.amount(1000); - op.issue_to_account = nathan.id; //({asset(), advanced.issuer, advanced.amount(1000), nathan.id}); + op.issuer = uia_id(db).issuer; + op.asset_to_issue = asset(1000, uia_id); + op.issue_to_account = nathan_id; trx.operations.emplace_back(op); - //Fail because nathan is not whitelisted. - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + set_expiration( db, trx ); + //Fail because nathan is not whitelisted, but only before hardfork time + if( db.head_block_time() <= HARDFORK_415_TIME ) + { + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + generate_blocks( HARDFORK_415_TIME ); + generate_block(); + set_expiration( db, trx ); + } + PUSH_TX( db, trx, ~0 ); + + BOOST_CHECK(nathan_id(db).is_authorized_asset(uia_id(db), db)); + BOOST_CHECK_EQUAL(get_balance(nathan_id, uia_id), 1000); + + // Make a whitelist, now it should fail + { + BOOST_TEST_MESSAGE( "Changing the whitelist authority" ); + asset_update_operation uop; + uop.issuer = izzy_id; + uop.asset_to_update = uia_id; + uop.new_options = uia_id(db).options; + uop.new_options.whitelist_authorities.insert(izzy_id); + trx.operations.back() = uop; + PUSH_TX( db, trx, ~0 ); + BOOST_CHECK( uia_id(db).options.whitelist_authorities.find(izzy_id) != uia_id(db).options.whitelist_authorities.end() ); + } + + // Fail because there is a whitelist authority and I'm not whitelisted + trx.operations.back() = op; + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, ~0 ), fc::exception ); account_whitelist_operation wop; - wop.authorizing_account = account_id_type(); - wop.account_to_list = nathan.id; + wop.authorizing_account = izzy_id; + wop.account_to_list = vikram_id; wop.new_listing = account_whitelist_operation::white_listed; trx.operations.back() = wop; + // Fail because whitelist function is restricted to members only + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, ~0 ), fc::exception ); + upgrade_to_lifetime_member( izzy_id ); + trx.operations.clear(); + trx.operations.push_back( wop ); PUSH_TX( db, trx, ~0 ); - BOOST_CHECK(nathan.is_authorized_asset(advanced)); + // Still fail after an irrelevant account was added + trx.operations.back() = op; + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, ~0 ), fc::exception ); + + wop.account_to_list = nathan_id; + trx.operations.back() = wop; + PUSH_TX( db, trx, ~0 ); trx.operations.back() = op; + BOOST_CHECK_EQUAL(get_balance(nathan_id, uia_id), 1000); + // Finally succeed when we were whitelisted PUSH_TX( db, trx, ~0 ); + BOOST_CHECK_EQUAL(get_balance(nathan_id, uia_id), 2000); - BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 1000); } catch(fc::exception& e) { edump((e.to_detail_string())); throw; @@ -174,6 +217,7 @@ const asset_object& advanced = get_asset("ADVANCED"); const account_object& nathan = get_account("nathan"); const account_object& dan = create_account("dan"); + account_id_type izzy_id = get_account("izzy").id; upgrade_to_lifetime_member(dan); trx.clear(); @@ -189,30 +233,51 @@ BOOST_TEST_MESSAGE( "Adding dan to whitelist for asset ADVANCED" ); account_whitelist_operation wop; - wop.authorizing_account = account_id_type(); + wop.authorizing_account = izzy_id; wop.account_to_list = dan.id; wop.new_listing = account_whitelist_operation::white_listed; trx.operations.back() = wop; PUSH_TX( db, trx, ~0 ); - BOOST_TEST_MESSAGE( "Attempting to trnsfer from nathan to dan after whitelisting dan, should succeed" ); + BOOST_TEST_MESSAGE( "Attempting to transfer from nathan to dan after whitelisting dan, should succeed" ); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); - BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 900); + BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 1900); BOOST_CHECK_EQUAL(get_balance(dan, advanced), 100); BOOST_TEST_MESSAGE( "Attempting to blacklist nathan" ); + { + BOOST_TEST_MESSAGE( "Changing the blacklist authority" ); + asset_update_operation uop; + uop.issuer = izzy_id; + uop.asset_to_update = advanced.id; + uop.new_options = advanced.options; + uop.new_options.blacklist_authorities.insert(izzy_id); + trx.operations.back() = uop; + PUSH_TX( db, trx, ~0 ); + BOOST_CHECK( advanced.options.blacklist_authorities.find(izzy_id) != advanced.options.blacklist_authorities.end() ); + } + wop.new_listing |= account_whitelist_operation::black_listed; wop.account_to_list = nathan.id; trx.operations.back() = wop; PUSH_TX( db, trx, ~0 ); + BOOST_CHECK( !(nathan.is_authorized_asset(advanced, db)) ); BOOST_TEST_MESSAGE( "Attempting to transfer from nathan after blacklisting, should fail" ); op.amount = advanced.amount(50); trx.operations.back() = op; //Fail because nathan is blacklisted - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), transfer_from_account_not_whitelisted ); - + if( db.head_block_time() <= HARDFORK_419_TIME ) + { + // before the hardfork time, it fails because the whitelist check fails + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), transfer_from_account_not_whitelisted ); + } + else + { + // after the hardfork time, it fails because the fees are not in a whitelisted asset + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception ); + } BOOST_TEST_MESSAGE( "Attempting to burn from nathan after blacklisting, should fail" ); asset_reserve_operation burn; @@ -230,6 +295,7 @@ { BOOST_TEST_MESSAGE( "Changing the blacklist authority to dan" ); asset_update_operation op; + op.issuer = izzy_id; op.asset_to_update = advanced.id; op.new_options = advanced.options; op.new_options.blacklist_authorities.clear(); @@ -242,7 +308,7 @@ BOOST_TEST_MESSAGE( "Attempting to transfer from dan back to nathan" ); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); - BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 950); + BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 1950); BOOST_CHECK_EQUAL(get_balance(dan, advanced), 50); BOOST_TEST_MESSAGE( "Blacklisting nathan by dan" ); @@ -254,11 +320,11 @@ trx.operations.back() = op; //Fail because nathan is blacklisted - BOOST_CHECK(!nathan.is_authorized_asset(advanced)); + BOOST_CHECK(!nathan.is_authorized_asset(advanced, db)); GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); //Remove nathan from committee's whitelist, add him to dan's. This should not authorize him to hold ADVANCED. - wop.authorizing_account = account_id_type(); + wop.authorizing_account = izzy_id; wop.account_to_list = nathan.id; wop.new_listing = account_whitelist_operation::no_listing; trx.operations.back() = wop; @@ -271,7 +337,7 @@ trx.operations.back() = op; //Fail because nathan is not whitelisted - BOOST_CHECK(!nathan.is_authorized_asset(advanced)); + BOOST_CHECK(!nathan.is_authorized_asset(advanced, db)); GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); burn.payer = dan.id; @@ -356,5 +422,52 @@ } } +BOOST_AUTO_TEST_CASE( asset_name_test ) +{ + try + { + ACTORS( (alice)(bob) ); + + auto has_asset = [&]( std::string symbol ) -> bool + { + const auto& assets_by_symbol = db.get_index_type().indices().get(); + return assets_by_symbol.find( symbol ) != assets_by_symbol.end(); + }; + + // Alice creates asset "ALPHA" + BOOST_CHECK( !has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + create_user_issued_asset( "ALPHA", alice_id(db), 0 ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + + // Nobody can create another asset named ALPHA + GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA", bob_id(db), 0 ), fc::exception ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA", alice_id(db), 0 ), fc::exception ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + + // Bob can't create ALPHA.ONE + GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", bob_id(db), 0 ), fc::exception ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + if( db.head_block_time() <= HARDFORK_409_TIME ) + { + // Alice can't create ALPHA.ONE before hardfork + GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", alice_id(db), 0 ), fc::exception ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + generate_blocks( HARDFORK_409_TIME ); + generate_block(); + // Bob can't create ALPHA.ONE after hardfork + GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "ALPHA.ONE", bob_id(db), 0 ), fc::exception ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( !has_asset("ALPHA.ONE") ); + } + // Alice can create it + create_user_issued_asset( "ALPHA.ONE", alice_id(db), 0 ); + BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( has_asset("ALPHA.ONE") ); + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} BOOST_AUTO_TEST_SUITE_END()