From 31e61890bf33c41eec429c38195399de76fef105 Mon Sep 17 00:00:00 2001 From: Jeffrey Paul Date: Wed, 30 Nov 2016 13:21:40 -0500 Subject: [PATCH 01/77] go back to single dockerfile (#640) * switching to single dockerfile * dummy commit to rebuild * dummy commit --- Dockerfile | 18 ++++++++++++++++++ Dockerfile.test | 20 -------------------- tests/scripts/Dockerfile.testenv | 24 ------------------------ tests/scripts/create-ci-docker-image.sh | 22 ---------------------- 4 files changed, 18 insertions(+), 66 deletions(-) delete mode 100644 Dockerfile.test delete mode 100644 tests/scripts/Dockerfile.testenv delete mode 100644 tests/scripts/create-ci-docker-image.sh diff --git a/Dockerfile b/Dockerfile index 9334e857c7..b85581b35c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,24 @@ RUN \ ADD . /usr/local/src/steem +RUN \ + cd /usr/local/src/steem && \ + git submodule update --init --recursive && \ + mkdir build && \ + cd build && \ + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_STEEM_TESTNET=ON \ + -DLOW_MEMORY_NODE=OFF \ + -DCLEAR_VOTES=ON \ + .. && \ + make -j$(nproc) chain_test && \ + ./tests/chain_test && \ + cd /usr/local/src/steem && \ + doxygen && \ + programs/build_helpers/check_reflect.py && \ + rm -rf /usr/local/src/steem/build + RUN \ cd /usr/local/src/steem && \ git submodule update --init --recursive && \ diff --git a/Dockerfile.test b/Dockerfile.test deleted file mode 100644 index 156cbeb77c..0000000000 --- a/Dockerfile.test +++ /dev/null @@ -1,20 +0,0 @@ -FROM steemitinc/ci-test-environment:latest - -ADD . /usr/local/src/steem - -RUN \ - cd /usr/local/src/steem && \ - git submodule update --init --recursive && \ - mkdir build && \ - cd build && \ - cmake \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_STEEM_TESTNET=ON \ - -DLOW_MEMORY_NODE=OFF \ - -DCLEAR_VOTES=ON \ - .. && \ - make -j$(nproc) chain_test && \ - ./tests/chain_test && \ - cd /usr/local/src/steem && \ - doxygen && \ - programs/build_helpers/check_reflect.py diff --git a/tests/scripts/Dockerfile.testenv b/tests/scripts/Dockerfile.testenv deleted file mode 100644 index 638fc15e8e..0000000000 --- a/tests/scripts/Dockerfile.testenv +++ /dev/null @@ -1,24 +0,0 @@ -FROM phusion/baseimage:0.9.19 - -RUN \ - apt-get update && \ - apt-get install -y \ - autoconf \ - automake \ - autotools-dev \ - bsdmainutils \ - build-essential \ - cmake \ - doxygen \ - git \ - libboost-all-dev \ - libreadline-dev \ - libssl-dev \ - libtool \ - ncurses-dev \ - pbzip2 \ - python3 \ - python3-dev \ - && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/tests/scripts/create-ci-docker-image.sh b/tests/scripts/create-ci-docker-image.sh deleted file mode 100644 index b9ec4e0511..0000000000 --- a/tests/scripts/create-ci-docker-image.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -set -x - -DOCKER_CACHE_DIR="$HOME/docker" - -if [[ ! -d $DOCKER_CACHE_DIR ]]; then - mkdir -p $DOCKER_CACHE_DIR -fi - -if [[ -e $DOCKER_CACHE_DIR/image.tar ]]; then - du -sh $DOCKER_CACHE_DIR/image.tar - docker load -i $DOCKER_CACHE_DIR/image.tar -else - docker build --rm=false \ - -t steemitinc/ci-test-environment:latest \ - -f tests/scripts/Dockerfile.testenv . && \ - mkdir -p ~/docker && \ - docker save steemitinc/ci-test-environment:latest \ - > $DOCKER_CACHE_DIR/image.tar.tmp && \ - mv $DOCKER_CACHE_DIR/image.tar.tmp $DOCKER_CACHE_DIR/image.tar && \ - du -sh $DOCKER_CACHE_DIR/image.tar -fi From 66e0e8ef1e23f95d4eb720b7e8dec570f77b96a4 Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 02:18:17 -0500 Subject: [PATCH 02/77] added ci build scripts to the repo so they can be version tracked and controlled independently from jenkins internal configuration --- ciscripts/buildfailure.sh | 6 ++++++ ciscripts/buildpending.sh | 6 ++++++ ciscripts/buildscript.sh | 6 ++++++ ciscripts/buildsuccess.sh | 6 ++++++ 4 files changed, 24 insertions(+) create mode 100755 ciscripts/buildfailure.sh create mode 100755 ciscripts/buildpending.sh create mode 100755 ciscripts/buildscript.sh create mode 100755 ciscripts/buildsuccess.sh diff --git a/ciscripts/buildfailure.sh b/ciscripts/buildfailure.sh new file mode 100755 index 0000000000..ca860730cb --- /dev/null +++ b/ciscripts/buildfailure.sh @@ -0,0 +1,6 @@ +#!/bin/bash +curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ + \"state\": \"failure\", + \"target_url\": \"${BUILD_URL}\", + \"description\": \"JenkinsCI reports the build has failed!\" +}" diff --git a/ciscripts/buildpending.sh b/ciscripts/buildpending.sh new file mode 100755 index 0000000000..69db4e9e13 --- /dev/null +++ b/ciscripts/buildpending.sh @@ -0,0 +1,6 @@ +#!/bin/bash +curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ + \"state\": \"pending\", + \"target_url\": \"${BUILD_URL}\", + \"description\": \"The build is now pending in jenkinsci!\" +}" diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh new file mode 100755 index 0000000000..cea0cd5901 --- /dev/null +++ b/ciscripts/buildscript.sh @@ -0,0 +1,6 @@ +#!/bin/bash +export IMAGE_NAME="steemit/steem:${GIT_BRANCH#*/}" +sudo docker build -t=$IMAGE_NAME . +sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS +sudo docker push $IMAGE_NAME +sudo rm -rf /tmp/ramdisk/* diff --git a/ciscripts/buildsuccess.sh b/ciscripts/buildsuccess.sh new file mode 100755 index 0000000000..bd1bdd4648 --- /dev/null +++ b/ciscripts/buildsuccess.sh @@ -0,0 +1,6 @@ +#/bin/bash +curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ + \"state\": \"success\", + \"target_url\": \"${BUILD_URL}\", + \"description\": \"Jenkins-CI reports build succeeded!!\" +}" From 025ddd1abe842c5ac24c6b8a54f9035bd8326d7d Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 02:37:47 -0500 Subject: [PATCH 03/77] added triggerbuild true/false check for builds --- ciscripts/triggerbuild.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 ciscripts/triggerbuild.sh diff --git a/ciscripts/triggerbuild.sh b/ciscripts/triggerbuild.sh new file mode 100755 index 0000000000..838760adcf --- /dev/null +++ b/ciscripts/triggerbuild.sh @@ -0,0 +1,7 @@ +#!/bin/bash +sh -x ./buildpending.sh +if sh -x ./buildscript.sh; then + echo BUILD SUCCESS +else + echo BUILD FAILURE +fi From 33c83c293c3e455ba391b1dfeea0c74664a85a56 Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 03:41:26 -0500 Subject: [PATCH 04/77] test --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index b85581b35c..e328e3d7d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +#test FROM phusion/baseimage:0.9.19 #ARG STEEMD_BLOCKCHAIN=https://example.com/steemd-blockchain.tbz2 From a3dd9a3e950044a65a022b78be1851734a89a4a4 Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 04:35:10 -0500 Subject: [PATCH 05/77] fixed ciscripts --- ciscripts/buildfailure.sh | 1 + ciscripts/buildscript.sh | 1 - ciscripts/buildsuccess.sh | 1 + ciscripts/triggerbuild.sh | 4 ++-- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ciscripts/buildfailure.sh b/ciscripts/buildfailure.sh index ca860730cb..08adb9f069 100755 --- a/ciscripts/buildfailure.sh +++ b/ciscripts/buildfailure.sh @@ -4,3 +4,4 @@ curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repo \"target_url\": \"${BUILD_URL}\", \"description\": \"JenkinsCI reports the build has failed!\" }" +rm -rf $WORKSPACE/* diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index cea0cd5901..b96c648a4b 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -3,4 +3,3 @@ export IMAGE_NAME="steemit/steem:${GIT_BRANCH#*/}" sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME -sudo rm -rf /tmp/ramdisk/* diff --git a/ciscripts/buildsuccess.sh b/ciscripts/buildsuccess.sh index bd1bdd4648..89cc1c1dd4 100755 --- a/ciscripts/buildsuccess.sh +++ b/ciscripts/buildsuccess.sh @@ -4,3 +4,4 @@ curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repo \"target_url\": \"${BUILD_URL}\", \"description\": \"Jenkins-CI reports build succeeded!!\" }" +rm -rf $WORKSPACE/* diff --git a/ciscripts/triggerbuild.sh b/ciscripts/triggerbuild.sh index 838760adcf..28e8cdcf6d 100755 --- a/ciscripts/triggerbuild.sh +++ b/ciscripts/triggerbuild.sh @@ -1,6 +1,6 @@ #!/bin/bash -sh -x ./buildpending.sh -if sh -x ./buildscript.sh; then +sh $WORKSPACE/ciscripts/buildpending.sh +if sh $WORKSPACE/ciscripts/buildscript.sh; then echo BUILD SUCCESS else echo BUILD FAILURE From 443a8916dfaa23e2818a21807707770765938cea Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 04:45:43 -0500 Subject: [PATCH 06/77] fixing slack channel integration and verifying build pending/succeeded on github --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e328e3d7d2..b85581b35c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,3 @@ -#test FROM phusion/baseimage:0.9.19 #ARG STEEMD_BLOCKCHAIN=https://example.com/steemd-blockchain.tbz2 From 33cbb58694864a514ffa50937fc934b9c027ceaa Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 1 Dec 2016 13:49:19 -0500 Subject: [PATCH 07/77] Show exception in error message, fix typo #646 --- libraries/app/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 7fe9b6218c..4a965d6bbc 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -333,7 +333,7 @@ namespace detail { } catch( fc::exception& e ) { - wlog( "Error conencting to remote RPC, network api forwarding disabled.", ("e", e.to_detail_string()) ); + wlog( "Error connecting to remote RPC, network api forwarding disabled. ${e}", ("e", e.to_detail_string()) ); } } } From dcfbf0fd0d0f684b4d92252c2a384edc15408901 Mon Sep 17 00:00:00 2001 From: JustinW Date: Thu, 1 Dec 2016 18:25:44 -0500 Subject: [PATCH 08/77] test --- ciscripts/triggerbuild.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ciscripts/triggerbuild.sh b/ciscripts/triggerbuild.sh index 28e8cdcf6d..18c6be12c0 100755 --- a/ciscripts/triggerbuild.sh +++ b/ciscripts/triggerbuild.sh @@ -1,5 +1,4 @@ #!/bin/bash -sh $WORKSPACE/ciscripts/buildpending.sh if sh $WORKSPACE/ciscripts/buildscript.sh; then echo BUILD SUCCESS else From 8406b67a9792b921fedaa0090cad6f626205d737 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 29 Nov 2016 16:38:39 -0500 Subject: [PATCH 09/77] Print free memory #635 --- libraries/chain/database.cpp | 10 +++++++++- libraries/chain/include/steemit/chain/database.hpp | 2 ++ libraries/chainbase | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index e6accb012d..60989d949d 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -171,7 +171,8 @@ void database::reindex( const fc::path& data_dir, const fc::path& shared_mem_dir { auto cur_block_num = itr.first.block_num(); if( cur_block_num % 100000 == 0 ) - std::cerr << " " << double( cur_block_num * 100 ) / last_block_num << "% " << cur_block_num << " of " << last_block_num << " \n"; + std::cerr << " " << double( cur_block_num * 100 ) / last_block_num << "% " << cur_block_num << " of " << last_block_num << + " (" << (get_free_memory() / (1024*1024)) << "M free)\n"; apply_block( itr.first, skip_flags ); itr = _block_log.read_block( itr.second ); } @@ -2959,6 +2960,13 @@ void database::apply_block( const signed_block& next_block, uint32_t skip ) } } + uint32_t free_gb = uint32_t(get_free_memory() / (1024*1024*1024)); + if( (free_gb < _last_free_gb_printed) || (free_gb > _last_free_gb_printed+1) ) + { + ilog( "Free memory is now ${n}G", ("n", free_gb) ); + _last_free_gb_printed = free_gb; + } + } FC_CAPTURE_AND_RETHROW( (next_block) ) } void database::_apply_block( const signed_block& next_block ) diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index dd5c0cae11..da6cbcb0f8 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -475,6 +475,8 @@ namespace steemit { namespace chain { uint32_t _flush_blocks = 0; uint32_t _next_flush_block = 0; + uint32_t _last_free_gb_printed = 0; + flat_map< std::string, std::shared_ptr< custom_operation_interpreter > > _custom_operation_interpreters; std::string _json_schema; }; diff --git a/libraries/chainbase b/libraries/chainbase index 4de0d495e6..a1ca930951 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 4de0d495e624a30f4b1cbf200e59716837886103 +Subproject commit a1ca93095197bbe9e2eb6716c28ee351cd95b174 From 2dfbd44bfa641e3cc90a121312ca5d8e04254e02 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 2 Dec 2016 14:30:53 -0500 Subject: [PATCH 10/77] Fix account name index #648 --- libraries/app/database_api.cpp | 2 +- .../chain/include/steemit/chain/account_object.hpp | 3 ++- .../protocol/include/steemit/protocol/types.hpp | 14 ++++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 4a916e7a22..58e987b93e 100755 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -465,7 +465,7 @@ set database_api::lookup_accounts(const string& lower_bound_name, uint32 set database_api_impl::lookup_accounts(const string& lower_bound_name, uint32_t limit)const { - //FC_ASSERT( limit <= 1000 ); + FC_ASSERT( limit <= 1000 ); const auto& accounts_by_name = _db.get_index().indices().get(); set result; diff --git a/libraries/chain/include/steemit/chain/account_object.hpp b/libraries/chain/include/steemit/chain/account_object.hpp index 4755098f23..2d2cd24a29 100644 --- a/libraries/chain/include/steemit/chain/account_object.hpp +++ b/libraries/chain/include/steemit/chain/account_object.hpp @@ -221,7 +221,8 @@ namespace steemit { namespace chain { ordered_unique< tag< by_id >, member< account_object, account_id_type, &account_object::id > >, ordered_unique< tag< by_name >, - member< account_object, account_name_type, &account_object::name > >, + member< account_object, account_name_type, &account_object::name >, + protocol::string_less >, ordered_unique< tag< by_proxy >, composite_key< account_object, member< account_object, account_name_type, &account_object::proxy >, diff --git a/libraries/protocol/include/steemit/protocol/types.hpp b/libraries/protocol/include/steemit/protocol/types.hpp index bca62c0077..8229055e03 100644 --- a/libraries/protocol/include/steemit/protocol/types.hpp +++ b/libraries/protocol/include/steemit/protocol/types.hpp @@ -82,10 +82,20 @@ namespace steemit { { const char* ap = (const char*)&a; const char* ab = (const char*)&b; - int count = sizeof(a); - while( *ap == *ab && count ) { ++ap; ++ab; --count; } + int count = sizeof(a) - 1; + while( *ap == *ab && count > 0 ) { ++ap; ++ab; --count; } return *ap < *ab; } + + bool operator()( const fc::fixed_string<>& a, const std::string& b )const + { + return std::string( a ) < b; + } + + bool operator()( const std::string& a, const fc::fixed_string<>& b )const + { + return a < std::string( b ); + } }; typedef fc::ripemd160 block_id_type; From c4761fed2762c8a4bee6b18a86ec08ea8c260132 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 2 Dec 2016 16:18:37 -0500 Subject: [PATCH 11/77] Bump fc #651 --- libraries/fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fc b/libraries/fc index d7276e2d15..2f202e017c 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit d7276e2d15c791674722741451a4ad51972428b8 +Subproject commit 2f202e017c2fef0ad622d70b0c04951960037461 From ec429559542e9fad1e9ad0d01bbf4d489710656c Mon Sep 17 00:00:00 2001 From: JustinW Date: Sun, 4 Dec 2016 19:23:24 -0500 Subject: [PATCH 12/77] testcommit --- ciscripts/buildsuccess.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ciscripts/buildsuccess.sh b/ciscripts/buildsuccess.sh index 89cc1c1dd4..d8ae62c641 100755 --- a/ciscripts/buildsuccess.sh +++ b/ciscripts/buildsuccess.sh @@ -1,4 +1,5 @@ #/bin/bash +#testcommit curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ \"state\": \"success\", \"target_url\": \"${BUILD_URL}\", From 4cf920faf608f2d467003fd592acaacb81dfa2bf Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 6 Dec 2016 09:55:57 -0500 Subject: [PATCH 13/77] Initial changes. Block log has bugs. --- libraries/chain/block_log.cpp | 3 +- libraries/chain/database.cpp | 32 ++++++++++++------- .../steemit/chain/block_summary_object.hpp | 3 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index 9814a0baa7..39bc6ada16 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -218,6 +218,7 @@ namespace steemit { namespace chain { my->index_stream.seekg( sizeof( uint64_t ) * ( block_num - 1 ) ); uint64_t pos; my->index_stream.read( (char*)&pos, sizeof( pos ) ); + idump( (block_num)(pos) ); return pos; } @@ -250,7 +251,7 @@ namespace steemit { namespace chain { { my->block_stream.seekg( start_pos ); fc::raw::unpack( my->block_stream, tmp ); - start_pos = uint64_t(my->block_stream.tellg()) + 8; + start_pos = uint64_t( my->block_stream.tellg() ) + 8; my->index_stream.write( (char*)&start_pos, sizeof( start_pos ) ); } } diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 60989d949d..8361d7f73a 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -268,9 +268,17 @@ optional database::fetch_block_by_number( uint32_t block_num )cons if( !stats ) return b; - signed_block block; - fc::raw::unpack( stats->packed_block, block ); - b = block; + if( stats->packed_block.size() ) + { + signed_block block; + fc::raw::unpack( stats->packed_block, block ); + b = block; + } + else + { + b = _block_log.read_block_by_num( stats->block_num() ); + } + return b; } @@ -3041,12 +3049,8 @@ void database::_apply_block( const signed_block& next_block ) { assert( bso.block_num() == next_block_num ); // Probably can be taken out. Sanity check bso.block_id = next_block_id; - fc::raw::pack( bso.packed_block, next_block ); - /* - auto size = fc::raw::pack_size( next_block ); - bso.packed_block.resize( size ); - fc::datastream ds( bso.packed_block.data(), size ); - fc::raw::pack( ds, next_block );*/ + if( !( get_node_properties().skip_flags & skip_block_log ) ) + fc::raw::pack( bso.packed_block, next_block ); }); update_global_dynamic_data(next_block); @@ -3523,9 +3527,9 @@ void database::update_last_irreversible_block() commit( dpo.last_irreversible_block_num ); - // output to block log based on new last irreverisible block num if( !( get_node_properties().skip_flags & skip_block_log ) ) { + // output to block log based on new last irreverisible block num const auto& tmp_head = _block_log.head(); uint64_t log_head_num = 0; @@ -3537,9 +3541,15 @@ void database::update_last_irreversible_block() while( log_head_num < dpo.last_irreversible_block_num ) { _block_log.append( *fetch_block_by_number( log_head_num + 1 ) ); + _block_log.flush(); + + modify( get< block_stats_object >( log_head_num + 1 ), [&]( block_stats_object& bso ) + { + bso.packed_block.clear(); + }); + log_head_num++; } - _block_log.flush(); } } } diff --git a/libraries/chain/include/steemit/chain/block_summary_object.hpp b/libraries/chain/include/steemit/chain/block_summary_object.hpp index c28d364111..b765d357d3 100644 --- a/libraries/chain/include/steemit/chain/block_summary_object.hpp +++ b/libraries/chain/include/steemit/chain/block_summary_object.hpp @@ -50,7 +50,6 @@ namespace steemit { namespace chain { id_type id; block_id_type block_id; - uint64_t pos = -1; bip::vector< char, allocator< char > > packed_block; uint64_t block_num()const { return id._id + 1; } @@ -74,5 +73,5 @@ namespace steemit { namespace chain { FC_REFLECT( steemit::chain::block_summary_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_summary_object, steemit::chain::block_summary_index ) -FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id)(pos)(packed_block) ) +FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id)(packed_block) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_stats_object, steemit::chain::block_stats_index ) From ca922da9dd55dab7f66c9d96425b2df5c1f9d18e Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 6 Dec 2016 10:40:55 -0500 Subject: [PATCH 14/77] Refactor add_index / add_index_plugin to be global methods #663 --- libraries/chain/database.cpp | 53 ++++++++++--------- .../chain/include/steemit/chain/database.hpp | 10 ++-- .../chain/include/steemit/chain/index.hpp | 25 +++++++++ .../account_by_key/account_by_key_plugin.cpp | 9 ++-- .../blockchain_statistics_plugin.cpp | 10 ++-- libraries/plugins/follow/follow_plugin.cpp | 16 +++--- .../market_history/market_history_plugin.cpp | 8 +-- .../private_message_plugin.cpp | 4 +- libraries/plugins/tags/tags_plugin.cpp | 8 +-- 9 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 libraries/chain/include/steemit/chain/index.hpp diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 60989d949d..ff50078c2e 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -2644,32 +2645,32 @@ std::shared_ptr< custom_operation_interpreter > database::get_custom_json_evalua void database::initialize_indexes() { - add_index< dynamic_global_property_index >(); - add_index< account_index >(); - add_index< account_authority_index >(); - add_index< witness_index >(); - add_index< transaction_index >(); - add_index< block_summary_index >(); - add_index< witness_schedule_index >(); - add_index< comment_index >(); - add_index< comment_vote_index >(); - add_index< witness_vote_index >(); - add_index< limit_order_index >(); - add_index< feed_history_index >(); - add_index< convert_request_index >(); - add_index< liquidity_reward_balance_index >(); - add_index< operation_index >(); - add_index< account_history_index >(); - add_index< category_index >(); - add_index< hardfork_property_index >(); - add_index< withdraw_vesting_route_index >(); - add_index< owner_authority_history_index >(); - add_index< account_recovery_request_index >(); - add_index< change_recovery_account_request_index >(); - add_index< escrow_index >(); - add_index< savings_withdraw_index >(); - add_index< decline_voting_rights_request_index >(); - add_index< block_stats_index >(); + add_core_index< dynamic_global_property_index >(*this); + add_core_index< account_index >(*this); + add_core_index< account_authority_index >(*this); + add_core_index< witness_index >(*this); + add_core_index< transaction_index >(*this); + add_core_index< block_summary_index >(*this); + add_core_index< witness_schedule_index >(*this); + add_core_index< comment_index >(*this); + add_core_index< comment_vote_index >(*this); + add_core_index< witness_vote_index >(*this); + add_core_index< limit_order_index >(*this); + add_core_index< feed_history_index >(*this); + add_core_index< convert_request_index >(*this); + add_core_index< liquidity_reward_balance_index >(*this); + add_core_index< operation_index >(*this); + add_core_index< account_history_index >(*this); + add_core_index< category_index >(*this); + add_core_index< hardfork_property_index >(*this); + add_core_index< withdraw_vesting_route_index >(*this); + add_core_index< owner_authority_history_index >(*this); + add_core_index< account_recovery_request_index >(*this); + add_core_index< change_recovery_account_request_index >(*this); + add_core_index< escrow_index >(*this); + add_core_index< savings_withdraw_index >(*this); + add_core_index< decline_voting_rights_request_index >(*this); + add_core_index< block_stats_index >(*this); _plugin_index_signal(); } diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index da6cbcb0f8..d4af8723a5 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -90,12 +90,6 @@ namespace steemit { namespace chain { void wipe(const fc::path& data_dir, const fc::path& shared_mem_dir, bool include_blocks); void close(bool rewind = true); - template< typename T > - void add_plugin_index() - { - _plugin_index_signal.connect( [&](){ add_index< T >(); } ); - } - //////////////////// db_block.cpp //////////////////// /** @@ -460,6 +454,10 @@ namespace steemit { namespace chain { block_log _block_log; + // this function needs access to _plugin_index_signal + template< typename MultiIndexType > + friend void add_plugin_index( database& db ); + fc::signal< void() > _plugin_index_signal; transaction_id_type _current_trx_id; diff --git a/libraries/chain/include/steemit/chain/index.hpp b/libraries/chain/include/steemit/chain/index.hpp new file mode 100644 index 0000000000..5e89eb060e --- /dev/null +++ b/libraries/chain/include/steemit/chain/index.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace steemit { namespace chain { + +template< typename MultiIndexType > +void _add_index_impl( database& db ) +{ + db.add_index< MultiIndexType >(); +} + +template< typename MultiIndexType > +void add_core_index( database& db ) +{ + _add_index_impl< MultiIndexType >(db); +} + +template< typename MultiIndexType > +void add_plugin_index( database& db ) +{ + db._plugin_index_signal.connect( [&db](){ _add_index_impl< MultiIndexType >(db); } ); +} + +} } diff --git a/libraries/plugins/account_by_key/account_by_key_plugin.cpp b/libraries/plugins/account_by_key/account_by_key_plugin.cpp index e6467f3a40..3b666c9961 100644 --- a/libraries/plugins/account_by_key/account_by_key_plugin.cpp +++ b/libraries/plugins/account_by_key/account_by_key_plugin.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include @@ -227,11 +229,12 @@ void account_by_key_plugin::plugin_initialize( const boost::program_options::var try { ilog( "Initializing account_by_key plugin" ); + chain::database& db = database(); - database().pre_apply_operation.connect( [&]( const operation_notification& o ){ my->pre_operation( o ); } ); - database().post_apply_operation.connect( [&]( const operation_notification& o ){ my->post_operation( o ); } ); + db.pre_apply_operation.connect( [&]( const operation_notification& o ){ my->pre_operation( o ); } ); + db.post_apply_operation.connect( [&]( const operation_notification& o ){ my->post_operation( o ); } ); - database().add_plugin_index< key_lookup_index >(); + add_plugin_index< key_lookup_index >(db); } FC_CAPTURE_AND_RETHROW() } diff --git a/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp b/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp index 34fe2584e4..ca6076eb0a 100644 --- a/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp +++ b/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace steemit { namespace blockchain_statistics { @@ -425,12 +426,13 @@ void blockchain_statistics_plugin::plugin_initialize( const boost::program_optio try { ilog( "chain_stats_plugin: plugin_initialize() begin" ); + chain::database& db = database(); - database().applied_block.connect( [&]( const signed_block& b ){ _my->on_block( b ); } ); - database().pre_apply_operation.connect( [&]( const operation_notification& o ){ _my->pre_operation( o ); } ); - database().post_apply_operation.connect( [&]( const operation_notification& o ){ _my->post_operation( o ); } ); + db.applied_block.connect( [&]( const signed_block& b ){ _my->on_block( b ); } ); + db.pre_apply_operation.connect( [&]( const operation_notification& o ){ _my->pre_operation( o ); } ); + db.post_apply_operation.connect( [&]( const operation_notification& o ){ _my->post_operation( o ); } ); - database().add_plugin_index< bucket_index >(); + add_plugin_index< bucket_index >(db); if( options.count( "chain-stats-bucket-size" ) ) { diff --git a/libraries/plugins/follow/follow_plugin.cpp b/libraries/plugins/follow/follow_plugin.cpp index 326275cffc..954dacb638 100644 --- a/libraries/plugins/follow/follow_plugin.cpp +++ b/libraries/plugins/follow/follow_plugin.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -353,15 +354,16 @@ void follow_plugin::plugin_initialize( const boost::program_options::variables_m try { ilog("Intializing follow plugin" ); + chain::database& db = database(); my->plugin_initialize(); - database().pre_apply_operation.connect( [&]( const operation_notification& o ){ my->pre_operation( o ); } ); - database().post_apply_operation.connect( [&]( const operation_notification& o ){ my->post_operation( o ); } ); - database().add_plugin_index< follow_index >(); - database().add_plugin_index< feed_index >(); - database().add_plugin_index< blog_index >(); - database().add_plugin_index< reputation_index >(); - database().add_plugin_index< follow_count_index >(); + db.pre_apply_operation.connect( [&]( const operation_notification& o ){ my->pre_operation( o ); } ); + db.post_apply_operation.connect( [&]( const operation_notification& o ){ my->post_operation( o ); } ); + add_plugin_index< follow_index >(db); + add_plugin_index< feed_index >(db); + add_plugin_index< blog_index >(db); + add_plugin_index< reputation_index >(db); + add_plugin_index< follow_count_index >(db); if( options.count( "follow-max-feed-size" ) ) { diff --git a/libraries/plugins/market_history/market_history_plugin.cpp b/libraries/plugins/market_history/market_history_plugin.cpp index d7a08df0cb..d3871bd635 100644 --- a/libraries/plugins/market_history/market_history_plugin.cpp +++ b/libraries/plugins/market_history/market_history_plugin.cpp @@ -1,6 +1,7 @@ #include #include +#include #include namespace steemit { namespace market_history { @@ -174,10 +175,11 @@ void market_history_plugin::plugin_initialize( const boost::program_options::var try { ilog( "market_history: plugin_initialize() begin" ); + chain::database& db = database(); - database().post_apply_operation.connect( [&]( const operation_notification& o ){ _my->update_market_histories( o ); } ); - database().add_plugin_index< bucket_index >(); - database().add_plugin_index< order_history_index >(); + db.post_apply_operation.connect( [&]( const operation_notification& o ){ _my->update_market_histories( o ); } ); + add_plugin_index< bucket_index >(db); + add_plugin_index< order_history_index >(db); if( options.count("bucket-size" ) ) { diff --git a/libraries/plugins/private_message/private_message_plugin.cpp b/libraries/plugins/private_message/private_message_plugin.cpp index 88df45b2ac..6924ae99f1 100644 --- a/libraries/plugins/private_message/private_message_plugin.cpp +++ b/libraries/plugins/private_message/private_message_plugin.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -136,7 +137,8 @@ void private_message_plugin::plugin_set_program_options( void private_message_plugin::plugin_initialize(const boost::program_options::variables_map& options) { ilog("Intializing private message plugin" ); - database().add_plugin_index< message_index >(); + chain::database& db = database(); + add_plugin_index< message_index >(db); app().register_api_factory("private_message_api"); diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index fa1b28e24d..33c2d573d2 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -388,9 +389,10 @@ void tags_plugin_impl::on_operation( const operation_notification& note ) { tags_plugin::tags_plugin( application* app ) : plugin( app ), my( new detail::tags_plugin_impl(*this) ) { - database().add_plugin_index< tag_index >(); - database().add_plugin_index< tag_stats_index >(); - database().add_plugin_index< peer_stats_index >(); + chain::database& db = database(); + add_plugin_index< tag_index >(db); + add_plugin_index< tag_stats_index >(db); + add_plugin_index< peer_stats_index >(db); } tags_plugin::~tags_plugin() From e95bc365ecaa4aef3b963a9546e77bf1edc18f2d Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 6 Dec 2016 14:23:37 -0500 Subject: [PATCH 15/77] Require peer to report chain_id #612 --- libraries/net/node.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index 2de6c18ca7..0375b4312f 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -1981,28 +1981,25 @@ namespace graphene { namespace net { namespace detail { } } } - if (originating_peer->chain_id) + if ( !originating_peer->chain_id || *originating_peer->chain_id != STEEMIT_CHAIN_ID ) { - if(*originating_peer->chain_id != STEEMIT_CHAIN_ID ) - { - wlog("Received hello message from peer running a node for different blockchain.", - ("my_chain_id", STEEMIT_CHAIN_ID)("their_chain_id", originating_peer->chain_id) ); + wlog("Received hello message from peer running a node for different blockchain.", + ("my_chain_id", STEEMIT_CHAIN_ID)("their_chain_id", originating_peer->chain_id) ); - std::ostringstream rejection_message; - rejection_message << "Your client is running a different chain id"; - connection_rejected_message connection_rejected(_user_agent_string, core_protocol_version, - originating_peer->get_socket().remote_endpoint(), - rejection_reason_code::different_chain, - rejection_message.str() ); + std::ostringstream rejection_message; + rejection_message << "Your client is running a different chain id"; + connection_rejected_message connection_rejected(_user_agent_string, core_protocol_version, + originating_peer->get_socket().remote_endpoint(), + rejection_reason_code::different_chain, + rejection_message.str() ); - originating_peer->their_state = peer_connection::their_connection_state::connection_rejected; - originating_peer->send_message( message( connection_rejected ) ); - // for this type of message, we're immediately disconnecting this peer, instead of trying to - // allowing her to ask us for peers (any of our peers will be on the same chain as us, so there's no - // benefit of sharing them) - disconnect_from_peer(originating_peer, "Your client is on a different chain, please specify different seed nodes"); - return; - } + originating_peer->their_state = peer_connection::their_connection_state::connection_rejected; + originating_peer->send_message( message( connection_rejected ) ); + // for this type of message, we're immediately disconnecting this peer, instead of trying to + // allowing her to ask us for peers (any of our peers will be on the same chain as us, so there's no + // benefit of sharing them) + disconnect_from_peer(originating_peer, "Your client is on a different chain, please specify different seed nodes"); + return; } if (already_connected_to_this_peer) { From b2baa5630d532a936d4287992059a33605fb668c Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 6 Dec 2016 19:07:17 -0500 Subject: [PATCH 16/77] Generically unbox pow2 static_variant #666 --- .../account_by_key/account_by_key_plugin.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libraries/plugins/account_by_key/account_by_key_plugin.cpp b/libraries/plugins/account_by_key/account_by_key_plugin.cpp index 3b666c9961..dc3a8858c0 100644 --- a/libraries/plugins/account_by_key/account_by_key_plugin.cpp +++ b/libraries/plugins/account_by_key/account_by_key_plugin.cpp @@ -75,6 +75,17 @@ struct pre_operation_visitor } }; +struct pow2_work_get_account_visitor +{ + typedef const account_name_type* result_type; + + template< typename WorkType > + result_type operator()( const WorkType& work )const + { + return &work.input.worker_account; + } +}; + struct post_operation_visitor { account_by_key_plugin& _plugin; @@ -112,7 +123,10 @@ struct post_operation_visitor void operator()( const pow2_operation& op )const { - auto acct_itr = _plugin.database().find< account_authority_object, by_account >( op.work.get< pow2 >().input.worker_account ); + const account_name_type* worker_account = op.work.visit( pow2_work_get_account_visitor() ); + if( worker_account == nullptr ) + return; + auto acct_itr = _plugin.database().find< account_authority_object, by_account >( *worker_account ); if( acct_itr ) _plugin.my->update_key_lookup( *acct_itr ); } From 51f99cabd124dedc20ccbc6cc1bde8c817c83775 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Wed, 7 Dec 2016 16:33:49 -0500 Subject: [PATCH 17/77] When blocks are written to log, they are removed from chain state memory #675 --- libraries/chain/block_log.cpp | 36 ++++++++++--------- libraries/chain/database.cpp | 9 +++-- .../chain/include/steemit/chain/block_log.hpp | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index 39bc6ada16..db6f09ea87 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -132,21 +132,18 @@ namespace steemit { namespace chain { if( block_pos < index_pos ) { ilog( "block_pos < index_pos, close and reopen index_stream" ); - my->index_stream.close(); - fc::remove_all( my->index_file ); - my->index_stream.open( my->index_file.generic_string().c_str(), LOG_WRITE ); - my->index_write = true; - construct_index( 0 ); + construct_index(); } else if( block_pos > index_pos ) { - construct_index( index_pos ); + ilog( "Index is incomplete" ); + construct_index(); } } else { - ilog( "Index is empty, rebuild it" ); - construct_index( 0 ); + ilog( "Index is empty" ); + construct_index(); } } else if( index_size ) @@ -204,7 +201,7 @@ namespace steemit { namespace chain { { optional< signed_block > b; uint64_t pos = get_block_pos( block_num ); - if( ~pos ) + if( !pos ) b = read_block( pos ).first; return b; } @@ -218,7 +215,6 @@ namespace steemit { namespace chain { my->index_stream.seekg( sizeof( uint64_t ) * ( block_num - 1 ) ); uint64_t pos; my->index_stream.read( (char*)&pos, sizeof( pos ) ); - idump( (block_num)(pos) ); return pos; } @@ -237,23 +233,29 @@ namespace steemit { namespace chain { return my->head; } - void block_log::construct_index( uint64_t start_pos ) + void block_log::construct_index() { + ilog( "Reconstructing Block Log Index..." ); + my->index_stream.close(); + fc::remove_all( my->index_file ); + my->index_stream.open( my->index_file.generic_string().c_str(), LOG_WRITE ); + my->index_write = true; + + uint64_t pos = 0; uint64_t end_pos; my->check_block_read(); - my->check_index_write(); my->block_stream.seekg( -sizeof( uint64_t), std::ios::end ); my->block_stream.read( (char*)&end_pos, sizeof( end_pos ) ); signed_block tmp; - while( start_pos < end_pos ) + my->block_stream.seekg( pos ); + + while( pos < end_pos ) { - my->block_stream.seekg( start_pos ); fc::raw::unpack( my->block_stream, tmp ); - start_pos = uint64_t( my->block_stream.tellg() ) + 8; - my->index_stream.write( (char*)&start_pos, sizeof( start_pos ) ); + my->block_stream.read( (char*)&pos, sizeof( pos ) ); + my->index_stream.write( (char*)&pos, sizeof( pos ) ); } } - } } diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 8361d7f73a..e3c623d9aa 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -160,7 +160,8 @@ void database::reindex( const fc::path& data_dir, const fc::path& shared_mem_dir skip_witness_schedule_check | skip_authority_check | skip_validate | /// no need to validate operations - skip_validate_invariants; + skip_validate_invariants | + skip_block_log; with_write_lock( [&]() { @@ -3541,15 +3542,17 @@ void database::update_last_irreversible_block() while( log_head_num < dpo.last_irreversible_block_num ) { _block_log.append( *fetch_block_by_number( log_head_num + 1 ) ); - _block_log.flush(); - modify( get< block_stats_object >( log_head_num + 1 ), [&]( block_stats_object& bso ) + // Block stats object IDs are block num - 1, so the ID is ( log_head_num + 1 ) - 1 + modify( get< block_stats_object >( log_head_num ), [&]( block_stats_object& bso ) { bso.packed_block.clear(); }); log_head_num++; } + + _block_log.flush(); } } } diff --git a/libraries/chain/include/steemit/chain/block_log.hpp b/libraries/chain/include/steemit/chain/block_log.hpp index 156fd636d8..b51dd5fe87 100644 --- a/libraries/chain/include/steemit/chain/block_log.hpp +++ b/libraries/chain/include/steemit/chain/block_log.hpp @@ -51,7 +51,7 @@ namespace steemit { namespace chain { const optional< signed_block >& head()const; private: - void construct_index( uint64_t start_pos ); + void construct_index(); std::unique_ptr my; }; From e21d608f2df59fc55961b5b512e67d5a0d04bcee Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 8 Dec 2016 11:40:58 -0500 Subject: [PATCH 18/77] Fix broken tests #675 --- libraries/chain/block_log.cpp | 2 +- libraries/chain/database.cpp | 2 +- tests/tests/block_tests.cpp | 4 +++- tests/tests/operation_time_tests.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index db6f09ea87..7daaa11700 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -201,7 +201,7 @@ namespace steemit { namespace chain { { optional< signed_block > b; uint64_t pos = get_block_pos( block_num ); - if( !pos ) + if( ~pos ) b = read_block( pos ).first; return b; } diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index e3c623d9aa..eff05b71e2 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -277,7 +277,7 @@ optional database::fetch_block_by_number( uint32_t block_num )cons } else { - b = _block_log.read_block_by_num( stats->block_num() ); + b = _block_log.read_block_by_num( block_num ); } return b; diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 5a254dac88..9c00c1d073 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -74,7 +74,9 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) 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 )); + auto block = db.fetch_block_by_number( cutoff_height ); + BOOST_REQUIRE( block.valid() ); + cutoff_block = *block; break; } } diff --git a/tests/tests/operation_time_tests.cpp b/tests/tests/operation_time_tests.cpp index b28a9eb24d..d6ec126a72 100644 --- a/tests/tests/operation_time_tests.cpp +++ b/tests/tests/operation_time_tests.cpp @@ -2558,7 +2558,7 @@ BOOST_AUTO_TEST_CASE( sbd_stability ) auto& gpo = db.get_dynamic_global_properties(); BOOST_REQUIRE( gpo.sbd_print_rate >= last_print_rate ); last_print_rate = gpo.sbd_print_rate; - db_plugin->debug_generate_blocks( debug_key, 1, ~0 ); + db_plugin->debug_generate_blocks( debug_key, 1, database::skip_witness_signature ); validate_database(); } From a65a463f4de57ebd1fa04ea43fe47111f8cb2a88 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 8 Dec 2016 15:00:17 -0500 Subject: [PATCH 19/77] Update GPO properties mirrored in witness_schedule_object #682 Also reduce the number of modify() calls needed --- libraries/chain/database.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index ff50078c2e..5f8be7b680 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -1509,32 +1509,33 @@ void database::update_median_witness_props() { return a->props.account_creation_fee.amount < b->props.account_creation_fee.amount; } ); - - modify( wso, [&]( witness_schedule_object& _wso ) - { - _wso.median_props.account_creation_fee = active[active.size()/2]->props.account_creation_fee; - } ); + asset median_account_creation_fee = active[active.size()/2]->props.account_creation_fee; /// sort them by maximum_block_size std::sort( active.begin(), active.end(), [&]( const witness_object* a, const witness_object* b ) { return a->props.maximum_block_size < b->props.maximum_block_size; } ); - - modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& p ) - { - p.maximum_block_size = active[active.size()/2]->props.maximum_block_size; - } ); + uint32_t median_maximum_block_size = active[active.size()/2]->props.maximum_block_size; /// sort them by sbd_interest_rate std::sort( active.begin(), active.end(), [&]( const witness_object* a, const witness_object* b ) { return a->props.sbd_interest_rate < b->props.sbd_interest_rate; } ); + uint16_t median_sbd_interest_rate = active[active.size()/2]->props.sbd_interest_rate; + + modify( wso, [&]( witness_schedule_object& _wso ) + { + _wso.median_props.account_creation_fee = median_account_creation_fee; + _wso.median_props.maximum_block_size = median_maximum_block_size; + _wso.median_props.sbd_interest_rate = median_sbd_interest_rate; + } ); - modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& p ) + modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& _dgpo ) { - p.sbd_interest_rate = active[active.size()/2]->props.sbd_interest_rate; + _dgpo.maximum_block_size = median_maximum_block_size; + _dgpo.sbd_interest_rate = median_sbd_interest_rate; } ); } From c34e6e6b378cdd014258961f31624691ef9e357f Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 8 Dec 2016 15:36:18 -0500 Subject: [PATCH 20/77] Implement signature stripping test #684 --- tests/tests/operation_tests.cpp | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 08fd562533..5ac4f7d9e0 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1057,6 +1057,60 @@ BOOST_AUTO_TEST_CASE( transfer_authorities ) FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( signature_stripping ) +{ + try + { + // Alice, Bob and Sam all have 2-of-3 multisig on corp. + // Legitimate tx signed by (Alice, Bob) goes through. + // Sam shouldn't be able to add or remove signatures to get the transaction to process multiple times. + + ACTORS( (alice)(bob)(sam)(corp) ) + fund( "corp", 10000 ); + + account_update_operation update_op; + update_op.account = "corp"; + update_op.active = authority( 2, "alice", 1, "bob", 1, "sam", 1 ); + + signed_transaction tx; + tx.set_expiration( db.head_block_time() + STEEMIT_MAX_TIME_UNTIL_EXPIRATION ); + tx.operations.push_back( update_op ); + + tx.sign( corp_private_key, db.get_chain_id() ); + db.push_transaction( tx, 0 ); + + tx.operations.clear(); + tx.signatures.clear(); + + transfer_operation transfer_op; + transfer_op.from = "corp"; + transfer_op.to = "sam"; + transfer_op.amount = ASSET( "1.000 TESTS" ); + + tx.operations.push_back( transfer_op ); + + tx.sign( alice_private_key, db.get_chain_id() ); + signature_type alice_sig = tx.signatures.back(); + STEEMIT_REQUIRE_THROW( db.push_transaction( tx, 0 ), tx_missing_active_auth ); + tx.sign( bob_private_key, db.get_chain_id() ); + signature_type bob_sig = tx.signatures.back(); + tx.sign( sam_private_key, db.get_chain_id() ); + signature_type sam_sig = tx.signatures.back(); + STEEMIT_REQUIRE_THROW( db.push_transaction( tx, 0 ), tx_irrelevant_sig ); + + tx.signatures.clear(); + tx.signatures.push_back( alice_sig ); + tx.signatures.push_back( bob_sig ); + db.push_transaction( tx, 0 ); + + tx.signatures.clear(); + tx.signatures.push_back( alice_sig ); + tx.signatures.push_back( sam_sig ); + STEEMIT_REQUIRE_THROW( db.push_transaction( tx, 0 ), fc::exception ); + } + FC_LOG_AND_RETHROW() +} + BOOST_AUTO_TEST_CASE( transfer_apply ) { try From 0dfef17536bb8c57b362c6eceb9323416b5247bc Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 8 Dec 2016 17:52:42 -0500 Subject: [PATCH 21/77] Save db() in local variable in evaluators --- libraries/chain/steem_evaluator.cpp | 739 +++++++++++++++------------- 1 file changed, 389 insertions(+), 350 deletions(-) diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 7bcfcdfd86..37088f234d 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -61,33 +61,34 @@ struct strcmp_equal void witness_update_evaluator::do_apply( const witness_update_operation& o ) { - db().get_account( o.owner ); // verify owner exists + database& _db = db(); + _db.get_account( o.owner ); // verify owner exists - if ( db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) + if ( _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { FC_ASSERT( o.url.size() <= STEEMIT_MAX_WITNESS_URL_LENGTH, "URL is too long" ); } else if( o.url.size() > STEEMIT_MAX_WITNESS_URL_LENGTH ) { // after HF, above check can be moved to validate() if reindex doesn't show this warning - wlog( "URL is too long in block ${b}", ("b", db().head_block_num()+1) ); + wlog( "URL is too long in block ${b}", ("b", _db.head_block_num()+1) ); } - if ( db().has_hardfork( STEEMIT_HARDFORK_0_14__410 ) ) + if ( _db.has_hardfork( STEEMIT_HARDFORK_0_14__410 ) ) { FC_ASSERT( o.props.account_creation_fee.symbol == STEEM_SYMBOL ); } else if( o.props.account_creation_fee.symbol != STEEM_SYMBOL ) { // after HF, above check can be moved to validate() if reindex doesn't show this warning - wlog( "Wrong fee symbol in block ${b}", ("b", db().head_block_num()+1) ); + wlog( "Wrong fee symbol in block ${b}", ("b", _db.head_block_num()+1) ); } - const auto& by_witness_name_idx = db().get_index< witness_index >().indices().get< by_name >(); + const auto& by_witness_name_idx = _db.get_index< witness_index >().indices().get< by_name >(); auto wit_itr = by_witness_name_idx.find( o.owner ); if( wit_itr != by_witness_name_idx.end() ) { - db().modify( *wit_itr, [&]( witness_object& w ) { + _db.modify( *wit_itr, [&]( witness_object& w ) { from_string( w.url, o.url ); w.signing_key = o.block_signing_key; w.props = o.props; @@ -95,11 +96,11 @@ void witness_update_evaluator::do_apply( const witness_update_operation& o ) } else { - db().create< witness_object >( [&]( witness_object& w ) { + _db.create< witness_object >( [&]( witness_object& w ) { w.owner = o.owner; from_string( w.url, o.url ); w.signing_key = o.block_signing_key; - w.created = db().head_block_time(); + w.created = _db.head_block_time(); w.props = o.props; }); } @@ -107,42 +108,43 @@ void witness_update_evaluator::do_apply( const witness_update_operation& o ) void account_create_evaluator::do_apply( const account_create_operation& o ) { - const auto& creator = db().get_account( o.creator ); + database& _db = db(); + const auto& creator = _db.get_account( o.creator ); - const auto& props = db().get_dynamic_global_properties(); + const auto& props = _db.get_dynamic_global_properties(); FC_ASSERT( creator.balance >= o.fee, "Insufficient balance to create account.", ( "creator.balance", creator.balance )( "required", o.fee ) ); - if( db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { - const witness_schedule_object& wso = db().get_witness_schedule_object(); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { + const witness_schedule_object& wso = _db.get_witness_schedule_object(); FC_ASSERT( o.fee >= wso.median_props.account_creation_fee, "Insufficient Fee: ${f} required, ${p} provided.", ("f", wso.median_props.account_creation_fee) ("p", o.fee) ); } - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) ) + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) ) { for( auto& a : o.owner.account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } for( auto& a : o.active.account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } for( auto& a : o.posting.account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - db().modify( creator, [&]( account_object& c ){ + _db.modify( creator, [&]( account_object& c ){ c.balance -= o.fee; }); - const auto& new_account = db().create< account_object >( [&]( account_object& acc ) + const auto& new_account = _db.create< account_object >( [&]( account_object& acc ) { acc.name = o.new_account_name; acc.memo_key = o.memo_key; @@ -150,7 +152,7 @@ void account_create_evaluator::do_apply( const account_create_operation& o ) acc.last_vote_time = props.time; acc.mined = false; - if( !db().has_hardfork( STEEMIT_HARDFORK_0_11__169 ) ) + if( !_db.has_hardfork( STEEMIT_HARDFORK_0_11__169 ) ) acc.recovery_account = "steem"; else acc.recovery_account = o.creator; @@ -161,7 +163,7 @@ void account_create_evaluator::do_apply( const account_create_operation& o ) #endif }); - db().create< account_authority_object >( [&]( account_authority_object& auth ) + _db.create< account_authority_object >( [&]( account_authority_object& auth ) { auth.account = o.new_account_name; auth.owner = o.owner; @@ -171,56 +173,57 @@ void account_create_evaluator::do_apply( const account_create_operation& o ) }); if( o.fee.amount > 0 ) - db().create_vesting( new_account, o.fee ); + _db.create_vesting( new_account, o.fee ); } void account_update_evaluator::do_apply( const account_update_operation& o ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) FC_ASSERT( o.account != STEEMIT_TEMP_ACCOUNT, "Cannot update temp account." ); + database& _db = db(); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) FC_ASSERT( o.account != STEEMIT_TEMP_ACCOUNT, "Cannot update temp account." ); - if( ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) && o.posting ) // TODO: Add HF 15 + if( ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) && o.posting ) // TODO: Add HF 15 o.posting->validate(); - const auto& account = db().get_account( o.account ); - const auto& account_auth = db().get< account_authority_object, by_account >( o.account ); + const auto& account = _db.get_account( o.account ); + const auto& account_auth = _db.get< account_authority_object, by_account >( o.account ); if( o.owner ) { #ifndef IS_TEST_NET - if( db().has_hardfork( STEEMIT_HARDFORK_0_11 ) ) - FC_ASSERT( db().head_block_time() - account_auth.last_owner_update > STEEMIT_OWNER_UPDATE_LIMIT, "Owner authority can only be updated once a minute." ); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_11 ) ) + FC_ASSERT( _db.head_block_time() - account_auth.last_owner_update > STEEMIT_OWNER_UPDATE_LIMIT, "Owner authority can only be updated once a minute." ); #endif - if( ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) ) // TODO: Add HF 15 + if( ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) ) // TODO: Add HF 15 { for( auto a: o.owner->account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - db().update_owner_authority( account, *o.owner ); + _db.update_owner_authority( account, *o.owner ); } - if( o.active && ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) ) // TODO: Add HF 15 + if( o.active && ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) ) // TODO: Add HF 15 { for( auto a: o.active->account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - if( o.posting && ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) ) // TODO: Add HF 15 + if( o.posting && ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) ) // TODO: Add HF 15 { for( auto a: o.posting->account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - db().modify( account, [&]( account_object& acc ) + _db.modify( account, [&]( account_object& acc ) { if( o.memo_key != public_key_type() ) acc.memo_key = o.memo_key; @@ -228,10 +231,10 @@ void account_update_evaluator::do_apply( const account_update_operation& o ) if( ( o.active || o.owner ) && acc.active_challenged ) { acc.active_challenged = false; - acc.last_active_proved = db().head_block_time(); + acc.last_active_proved = _db.head_block_time(); } - acc.last_account_update = db().head_block_time(); + acc.last_account_update = _db.head_block_time(); #ifndef IS_LOW_MEM if ( o.json_metadata.size() > 0 ) @@ -241,7 +244,7 @@ void account_update_evaluator::do_apply( const account_update_operation& o ) if( o.active || o.posting ) { - db().modify( account_auth, [&]( account_authority_object& auth) + _db.modify( account_auth, [&]( account_authority_object& auth) { if( o.active ) auth.active = *o.active; if( o.posting ) auth.posting = *o.posting; @@ -254,44 +257,46 @@ void account_update_evaluator::do_apply( const account_update_operation& o ) /** * Because net_rshares is 0 there is no need to update any pending payout calculations or parent posts. */ -void delete_comment_evaluator::do_apply( const delete_comment_operation& o ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_10 ) ) +void delete_comment_evaluator::do_apply( const delete_comment_operation& o ) +{ + database& _db = db(); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_10 ) ) { - const auto& auth = db().get_account( o.author ); + const auto& auth = _db.get_account( o.author ); FC_ASSERT( !(auth.owner_challenged || auth.active_challenged ), "Operation cannot be processed because account is currently challenged." ); } - const auto& comment = db().get_comment( o.author, o.permlink ); + const auto& comment = _db.get_comment( o.author, o.permlink ); FC_ASSERT( comment.children == 0, "Cannot delete a comment with replies." ); - if( db().is_producing() ) { + if( _db.is_producing() ) { FC_ASSERT( comment.net_rshares <= 0, "Cannot delete a comment with net positive votes." ); } if( comment.net_rshares > 0 ) return; - const auto& vote_idx = db().get_index().indices().get(); + const auto& vote_idx = _db.get_index().indices().get(); auto vote_itr = vote_idx.lower_bound( comment_id_type(comment.id) ); while( vote_itr != vote_idx.end() && vote_itr->comment == comment.id ) { const auto& cur_vote = *vote_itr; ++vote_itr; - db().remove(cur_vote); + _db.remove(cur_vote); } /// this loop can be skiped for validate-only nodes as it is merely gathering stats for indicies - if( db().has_hardfork( STEEMIT_HARDFORK_0_6__80 ) && comment.parent_author != STEEMIT_ROOT_POST_PARENT ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_6__80 ) && comment.parent_author != STEEMIT_ROOT_POST_PARENT ) { - auto parent = &db().get_comment( comment.parent_author, comment.parent_permlink ); - auto now = db().head_block_time(); + auto parent = &_db.get_comment( comment.parent_author, comment.parent_permlink ); + auto now = _db.head_block_time(); while( parent ) { - db().modify( *parent, [&]( comment_object& p ){ + _db.modify( *parent, [&]( comment_object& p ){ p.children--; p.active = now; }); #ifndef IS_LOW_MEM if( parent->parent_author != STEEMIT_ROOT_POST_PARENT ) - parent = &db().get_comment( parent->parent_author, parent->parent_permlink ); + parent = &_db.get_comment( parent->parent_author, parent->parent_permlink ); else #endif parent = nullptr; @@ -299,26 +304,27 @@ void delete_comment_evaluator::do_apply( const delete_comment_operation& o ) { } /** TODO move category behavior to a plugin, this is not part of consensus */ - const category_object* cat = db().find_category( comment.category ); - db().modify( *cat, [&]( category_object& c ) + const category_object* cat = _db.find_category( comment.category ); + _db.modify( *cat, [&]( category_object& c ) { c.discussions--; - c.last_update = db().head_block_time(); + c.last_update = _db.head_block_time(); }); - db().remove( comment ); + _db.remove( comment ); } void comment_options_evaluator::do_apply( const comment_options_operation& o ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_10 ) ) + database& _db = db(); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_10 ) ) { - const auto& auth = db().get_account( o.author ); + const auto& auth = _db.get_account( o.author ); FC_ASSERT( !(auth.owner_challenged || auth.active_challenged ), "Operation cannot be processed because account is currently challenged." ); } - const auto& comment = db().get_comment( o.author, o.permlink ); + const auto& comment = _db.get_comment( o.author, o.permlink ); if( !o.allow_curation_rewards || !o.allow_votes || o.max_accepted_payout < comment.max_accepted_payout ) FC_ASSERT( comment.abs_rshares == 0, "One of the included comment options requires the comment to have no rshares allocated to it." ); @@ -328,7 +334,7 @@ void comment_options_evaluator::do_apply( const comment_options_operation& o ) FC_ASSERT( comment.max_accepted_payout >= o.max_accepted_payout, "A comment cannot accept a greater payout." ); FC_ASSERT( comment.percent_steem_dollars >= o.percent_steem_dollars, "A comment cannot accept a greater percent SBD." ); - db().modify( comment, [&]( comment_object& c ) { + _db.modify( comment, [&]( comment_object& c ) { c.max_accepted_payout = o.max_accepted_payout; c.percent_steem_dollars = o.percent_steem_dollars; c.allow_votes = o.allow_votes; @@ -337,43 +343,45 @@ void comment_options_evaluator::do_apply( const comment_options_operation& o ) } void comment_evaluator::do_apply( const comment_operation& o ) { try { - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_5__55 ) ) + database& _db = db(); + + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_5__55 ) ) FC_ASSERT( o.title.size() + o.body.size() + o.json_metadata.size(), "Cannot update comment because nothing appears to be changing." ); - const auto& by_permlink_idx = db().get_index< comment_index >().indices().get< by_permlink >(); + const auto& by_permlink_idx = _db.get_index< comment_index >().indices().get< by_permlink >(); auto itr = by_permlink_idx.find( boost::make_tuple( o.author, o.permlink ) ); - const auto& auth = db().get_account( o.author ); /// prove it exists + const auto& auth = _db.get_account( o.author ); /// prove it exists - if( db().has_hardfork( STEEMIT_HARDFORK_0_10 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_10 ) ) FC_ASSERT( !(auth.owner_challenged || auth.active_challenged ), "Operation cannot be processed because account is currently challenged." ); comment_id_type id; const comment_object* parent = nullptr; if( o.parent_author != STEEMIT_ROOT_POST_PARENT ) { - parent = &db().get_comment( o.parent_author, o.parent_permlink ); + parent = &_db.get_comment( o.parent_author, o.parent_permlink ); FC_ASSERT( parent->depth < STEEMIT_MAX_COMMENT_DEPTH, "Comment is nested ${x} posts deep, maximum depth is ${y}.", ("x",parent->depth)("y",STEEMIT_MAX_COMMENT_DEPTH) ); } - auto now = db().head_block_time(); + auto now = _db.head_block_time(); if ( itr == by_permlink_idx.end() ) { if( o.parent_author != STEEMIT_ROOT_POST_PARENT ) { - FC_ASSERT( parent->root_comment( db() ).allow_replies, "The parent comment has disabled replies." ); - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177) ) - FC_ASSERT( db().calculate_discussion_payout_time( *parent ) != fc::time_point_sec::maximum(), "Discussion is frozen." ); + FC_ASSERT( parent->root_comment( _db ).allow_replies, "The parent comment has disabled replies." ); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177) ) + FC_ASSERT( _db.calculate_discussion_payout_time( *parent ) != fc::time_point_sec::maximum(), "Discussion is frozen." ); } - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__176 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) ) { if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) FC_ASSERT( (now - auth.last_root_post) > STEEMIT_MIN_ROOT_COMMENT_INTERVAL, "You may only post once every 5 minutes.", ("now",now)("auth.last_root_post",auth.last_root_post) ); else FC_ASSERT( (now - auth.last_post) > STEEMIT_MIN_REPLY_INTERVAL, "You may only comment once every 20 seconds.", ("now",now)("auth.last_post",auth.last_post) ); } - else if( db().has_hardfork( STEEMIT_HARDFORK_0_6__113 ) ) + else if( _db.has_hardfork( STEEMIT_HARDFORK_0_6__113 ) ) { if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) FC_ASSERT( (now - auth.last_post) > STEEMIT_MIN_ROOT_COMMENT_INTERVAL, "You may only post once every 5 minutes.", ("now",now)("auth.last_post",auth.last_post) ); @@ -388,15 +396,15 @@ void comment_evaluator::do_apply( const comment_operation& o ) uint16_t reward_weight = STEEMIT_100_PERCENT; uint64_t post_bandwidth = auth.post_bandwidth; - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__176 ) && o.parent_author == STEEMIT_ROOT_POST_PARENT ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) && o.parent_author == STEEMIT_ROOT_POST_PARENT ) { - uint64_t post_delta_time = std::min( db().head_block_time().sec_since_epoch() - auth.last_root_post.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); + uint64_t post_delta_time = std::min( _db.head_block_time().sec_since_epoch() - auth.last_root_post.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); uint32_t old_weight = uint32_t( ( post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - post_delta_time ) ) / STEEMIT_POST_AVERAGE_WINDOW ); post_bandwidth = ( old_weight + STEEMIT_100_PERCENT ); reward_weight = uint16_t( std::min( ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( post_bandwidth * post_bandwidth ), uint64_t( STEEMIT_100_PERCENT ) ) ); } - db().modify( auth, [&]( account_object& a ) { + _db.modify( auth, [&]( account_object& a ) { if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) { a.last_root_post = now; @@ -406,9 +414,9 @@ void comment_evaluator::do_apply( const comment_operation& o ) a.post_count++; }); - const auto& new_comment = db().create< comment_object >( [&]( comment_object& com ) + const auto& new_comment = _db.create< comment_object >( [&]( comment_object& com ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { validate_permlink_0_1( o.parent_permlink ); validate_permlink_0_1( o.permlink ); @@ -416,7 +424,7 @@ void comment_evaluator::do_apply( const comment_operation& o ) com.author = o.author; from_string( com.permlink, o.permlink ); - com.last_update = db().head_block_time(); + com.last_update = _db.head_block_time(); com.created = com.last_update; com.active = com.last_update; com.last_payout = fc::time_point_sec::min(); @@ -429,8 +437,8 @@ void comment_evaluator::do_apply( const comment_operation& o ) from_string( com.parent_permlink, o.parent_permlink ); from_string( com.category, o.parent_permlink ); com.root_comment = com.id; - com.cashout_time = db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) ? - db().head_block_time() + STEEMIT_CASHOUT_WINDOW_SECONDS : + com.cashout_time = _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) ? + _db.head_block_time() + STEEMIT_CASHOUT_WINDOW_SECONDS : fc::time_point_sec::maximum(); } else @@ -454,32 +462,32 @@ void comment_evaluator::do_apply( const comment_operation& o ) }); /** TODO move category behavior to a plugin, this is not part of consensus */ - const category_object* cat = db().find_category( new_comment.category ); + const category_object* cat = _db.find_category( new_comment.category ); if( !cat ) { - cat = &db().create( [&]( category_object& c ){ + cat = &_db.create( [&]( category_object& c ){ c.name = new_comment.category; c.discussions = 1; - c.last_update = db().head_block_time(); + c.last_update = _db.head_block_time(); }); } else { - db().modify( *cat, [&]( category_object& c ){ + _db.modify( *cat, [&]( category_object& c ){ c.discussions++; - c.last_update = db().head_block_time(); + c.last_update = _db.head_block_time(); }); } id = new_comment.id; /// this loop can be skiped for validate-only nodes as it is merely gathering stats for indicies - auto now = db().head_block_time(); + auto now = _db.head_block_time(); while( parent ) { - db().modify( *parent, [&]( comment_object& p ){ + _db.modify( *parent, [&]( comment_object& p ){ p.children++; p.active = now; }); #ifndef IS_LOW_MEM if( parent->parent_author != STEEMIT_ROOT_POST_PARENT ) - parent = &db().get_comment( parent->parent_author, parent->parent_permlink ); + parent = &_db.get_comment( parent->parent_author, parent->parent_permlink ); else #endif parent = nullptr; @@ -490,14 +498,14 @@ void comment_evaluator::do_apply( const comment_operation& o ) { const auto& comment = *itr; - if( db().has_hardfork( STEEMIT_HARDFORK_0_14__306 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_14__306 ) ) FC_ASSERT( comment.mode != archived, "The comment is archived." ); - else if( db().has_hardfork( STEEMIT_HARDFORK_0_10 ) ) + else if( _db.has_hardfork( STEEMIT_HARDFORK_0_10 ) ) FC_ASSERT( comment.last_payout == fc::time_point_sec::min(), "Can only edit during the first 24 hours." ); - db().modify( comment, [&]( comment_object& com ) + _db.modify( comment, [&]( comment_object& com ) { - com.last_update = db().head_block_time(); + com.last_update = _db.head_block_time(); com.active = com.last_update; strcmp_equal equal; @@ -547,12 +555,14 @@ void escrow_transfer_evaluator::do_apply( const escrow_transfer_operation& o ) { try { - const auto& from_account = db().get_account(o.from); - db().get_account(o.to); - db().get_account(o.agent); + database& _db = db(); - FC_ASSERT( o.ratification_deadline > db().head_block_time(), "The escorw ratification deadline must be after head block time." ); - FC_ASSERT( o.escrow_expiration > db().head_block_time(), "The escrow expiration must be after head block time." ); + const auto& from_account = _db.get_account(o.from); + _db.get_account(o.to); + _db.get_account(o.agent); + + FC_ASSERT( o.ratification_deadline > _db.head_block_time(), "The escorw ratification deadline must be after head block time." ); + FC_ASSERT( o.escrow_expiration > _db.head_block_time(), "The escrow expiration must be after head block time." ); asset steem_spent = o.steem_amount; asset sbd_spent = o.sbd_amount; @@ -564,10 +574,10 @@ void escrow_transfer_evaluator::do_apply( const escrow_transfer_operation& o ) FC_ASSERT( from_account.balance >= steem_spent, "Account cannot cover STEEM costs of escrow. Required: ${r} Available: ${a}", ("r",steem_spent)("a",from_account.balance) ); FC_ASSERT( from_account.sbd_balance >= sbd_spent, "Account cannot cover SBD costs of escrow. Required: ${r} Available: ${a}", ("r",sbd_spent)("a",from_account.sbd_balance) ); - db().adjust_balance( from_account, -steem_spent ); - db().adjust_balance( from_account, -sbd_spent ); + _db.adjust_balance( from_account, -steem_spent ); + _db.adjust_balance( from_account, -sbd_spent ); - db().create([&]( escrow_object& esc ) + _db.create([&]( escrow_object& esc ) { esc.escrow_id = o.escrow_id; esc.from = o.from; @@ -587,11 +597,12 @@ void escrow_approve_evaluator::do_apply( const escrow_approve_operation& o ) { try { - const auto& escrow = db().get_escrow( o.from, o.escrow_id ); + database& _db = db(); + const auto& escrow = _db.get_escrow( o.from, o.escrow_id ); FC_ASSERT( escrow.to == o.to, "Operation 'to' (${o}) does not match escrow 'to' (${e}).", ("o", o.to)("e", escrow.to) ); FC_ASSERT( escrow.agent == o.agent, "Operation 'agent' (${a}) does not match escrow 'agent' (${e}).", ("o", o.agent)("e", escrow.agent) ); - FC_ASSERT( escrow.ratification_deadline >= db().head_block_time(), "The escrow ratification deadline has passed. Escrow can no longer be ratified." ); + FC_ASSERT( escrow.ratification_deadline >= _db.head_block_time(), "The escrow ratification deadline has passed. Escrow can no longer be ratified." ); bool reject_escrow = !o.approve; @@ -601,7 +612,7 @@ void escrow_approve_evaluator::do_apply( const escrow_approve_operation& o ) if( !reject_escrow ) { - db().modify( escrow, [&]( escrow_object& esc ) + _db.modify( escrow, [&]( escrow_object& esc ) { esc.to_approved = true; }); @@ -613,7 +624,7 @@ void escrow_approve_evaluator::do_apply( const escrow_approve_operation& o ) if( !reject_escrow ) { - db().modify( escrow, [&]( escrow_object& esc ) + _db.modify( escrow, [&]( escrow_object& esc ) { esc.agent_approved = true; }); @@ -622,19 +633,19 @@ void escrow_approve_evaluator::do_apply( const escrow_approve_operation& o ) if( reject_escrow ) { - const auto& from_account = db().get_account( o.from ); - db().adjust_balance( from_account, escrow.steem_balance ); - db().adjust_balance( from_account, escrow.sbd_balance ); - db().adjust_balance( from_account, escrow.pending_fee ); + const auto& from_account = _db.get_account( o.from ); + _db.adjust_balance( from_account, escrow.steem_balance ); + _db.adjust_balance( from_account, escrow.sbd_balance ); + _db.adjust_balance( from_account, escrow.pending_fee ); - db().remove( escrow ); + _db.remove( escrow ); } else if( escrow.to_approved && escrow.agent_approved ) { - const auto& agent_account = db().get_account( o.agent ); - db().adjust_balance( agent_account, escrow.pending_fee ); + const auto& agent_account = _db.get_account( o.agent ); + _db.adjust_balance( agent_account, escrow.pending_fee ); - db().modify( escrow, [&]( escrow_object& esc ) + _db.modify( escrow, [&]( escrow_object& esc ) { esc.pending_fee.amount = 0; }); @@ -647,16 +658,17 @@ void escrow_dispute_evaluator::do_apply( const escrow_dispute_operation& o ) { try { - db().get_account( o.from ); // Verify from account exists + database& _db = db(); + _db.get_account( o.from ); // Verify from account exists - const auto& e = db().get_escrow( o.from, o.escrow_id ); - FC_ASSERT( db().head_block_time() < e.escrow_expiration, "Disputing the escrow must happen before expiration." ); + const auto& e = _db.get_escrow( o.from, o.escrow_id ); + FC_ASSERT( _db.head_block_time() < e.escrow_expiration, "Disputing the escrow must happen before expiration." ); FC_ASSERT( e.to_approved && e.agent_approved, "The escrow must be approved by all parties before a dispute can be raised." ); FC_ASSERT( !e.disputed, "The escrow is already under dispute." ); FC_ASSERT( e.to == o.to, "Operation 'to' (${o}) does not match escrow 'to' (${e}).", ("o", o.to)("e", e.to) ); FC_ASSERT( e.agent == o.agent, "Operation 'agent' (${a}) does not match escrow 'agent' (${e}).", ("o", o.agent)("e", e.agent) ); - db().modify( e, [&]( escrow_object& esc ) + _db.modify( e, [&]( escrow_object& esc ) { esc.disputed = true; }); @@ -668,10 +680,11 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o ) { try { - db().get_account(o.from); // Verify from account exists - const auto& receiver_account = db().get_account(o.receiver); + database& _db = db(); + _db.get_account(o.from); // Verify from account exists + const auto& receiver_account = _db.get_account(o.receiver); - const auto& e = db().get_escrow( o.from, o.escrow_id ); + const auto& e = _db.get_escrow( o.from, o.escrow_id ); FC_ASSERT( e.steem_balance >= o.steem_amount, "Release amount exceeds escrow balance. Amount: ${a}, Balance: ${b}", ("a", o.steem_amount)("b", e.steem_balance) ); FC_ASSERT( e.sbd_balance >= o.sbd_amount, "Release amount exceeds escrow balance. Amount: ${a}, Balance: ${b}", ("a", o.sbd_amount)("b", e.sbd_balance) ); FC_ASSERT( e.to == o.to, "Operation 'to' (${o}) does not match escrow 'to' (${e}).", ("o", o.to)("e", e.to) ); @@ -688,7 +701,7 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o ) { FC_ASSERT( o.who == e.from || o.who == e.to, "Only 'from' (${f}) and 'to' (${t}) can release funds from a non-disputed escrow", ("f", e.from)("t", e.to) ); - if( e.escrow_expiration > db().head_block_time() ) + if( e.escrow_expiration > _db.head_block_time() ) { // If there is no dispute and escrow has not expired, either party can release funds to the other. if( o.who == e.from ) @@ -703,10 +716,10 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o ) } // If escrow expires and there is no dispute, either party can release funds to either party. - db().adjust_balance( receiver_account, o.steem_amount ); - db().adjust_balance( receiver_account, o.sbd_amount ); + _db.adjust_balance( receiver_account, o.steem_amount ); + _db.adjust_balance( receiver_account, o.sbd_amount ); - db().modify( e, [&]( escrow_object& esc ) + _db.modify( e, [&]( escrow_object& esc ) { esc.steem_balance -= o.steem_amount; esc.sbd_balance -= o.sbd_amount; @@ -714,7 +727,7 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o ) if( e.steem_balance.amount == 0 && e.sbd_balance.amount == 0 ) { - db().remove( e ); + _db.remove( e ); } } FC_CAPTURE_AND_RETHROW( (o) ) @@ -722,58 +735,63 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o ) void transfer_evaluator::do_apply( const transfer_operation& o ) { - const auto& from_account = db().get_account(o.from); - const auto& to_account = db().get_account(o.to); + database& _db = db(); + const auto& from_account = _db.get_account(o.from); + const auto& to_account = _db.get_account(o.to); if( from_account.active_challenged ) { - db().modify( from_account, [&]( account_object& a ) + _db.modify( from_account, [&]( account_object& a ) { a.active_challenged = false; - a.last_active_proved = db().head_block_time(); + a.last_active_proved = _db.head_block_time(); }); } - FC_ASSERT( db().get_balance( from_account, o.amount.symbol ) >= o.amount, "Account does not have sufficient funds for transfer." ); - db().adjust_balance( from_account, -o.amount ); - db().adjust_balance( to_account, o.amount ); + FC_ASSERT( _db.get_balance( from_account, o.amount.symbol ) >= o.amount, "Account does not have sufficient funds for transfer." ); + _db.adjust_balance( from_account, -o.amount ); + _db.adjust_balance( to_account, o.amount ); } void transfer_to_vesting_evaluator::do_apply( const transfer_to_vesting_operation& o ) { - const auto& from_account = db().get_account(o.from); - const auto& to_account = o.to.size() ? db().get_account(o.to) : from_account; + database& _db = db(); + + const auto& from_account = _db.get_account(o.from); + const auto& to_account = o.to.size() ? _db.get_account(o.to) : from_account; - FC_ASSERT( db().get_balance( from_account, STEEM_SYMBOL) >= o.amount, "Account does not have sufficient STEEM for transfer." ); - db().adjust_balance( from_account, -o.amount ); - db().create_vesting( to_account, o.amount ); + FC_ASSERT( _db.get_balance( from_account, STEEM_SYMBOL) >= o.amount, "Account does not have sufficient STEEM for transfer." ); + _db.adjust_balance( from_account, -o.amount ); + _db.create_vesting( to_account, o.amount ); } void withdraw_vesting_evaluator::do_apply( const withdraw_vesting_operation& o ) { - const auto& account = db().get_account( o.account ); + database& _db = db(); + + const auto& account = _db.get_account( o.account ); FC_ASSERT( account.vesting_shares >= asset( 0, VESTS_SYMBOL ), "Account does not have sufficient Steem Power for withdraw." ); FC_ASSERT( account.vesting_shares >= o.vesting_shares, "Account does not have sufficient Steem Power for withdraw." ); - if( !account.mined && db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) + if( !account.mined && _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { - const auto& props = db().get_dynamic_global_properties(); - const witness_schedule_object& wso = db().get_witness_schedule_object(); + const auto& props = _db.get_dynamic_global_properties(); + const witness_schedule_object& wso = _db.get_witness_schedule_object(); asset min_vests = wso.median_props.account_creation_fee * props.get_vesting_share_price(); min_vests.amount.value *= 10; - FC_ASSERT( account.vesting_shares > min_vests || ( db().has_hardfork( STEEMIT_HARDFORK_0_16__562 ) && o.vesting_shares.amount == 0 ), + FC_ASSERT( account.vesting_shares > min_vests || ( _db.has_hardfork( STEEMIT_HARDFORK_0_16__562 ) && o.vesting_shares.amount == 0 ), "Account registered by another account requires 10x account creation fee worth of Steem Power before it can be powered down." ); } if( o.vesting_shares.amount == 0 ) { - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_5__57 ) ) + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_5__57 ) ) FC_ASSERT( account.vesting_withdraw_rate.amount != 0, "This operation would not change the vesting withdraw rate." ); - db().modify( account, [&]( account_object& a ) { + _db.modify( account, [&]( account_object& a ) { a.vesting_withdraw_rate = asset( 0, VESTS_SYMBOL ); a.next_vesting_withdrawal = time_point_sec::maximum(); a.to_withdraw = 0; @@ -783,21 +801,21 @@ void withdraw_vesting_evaluator::do_apply( const withdraw_vesting_operation& o ) else { int vesting_withdraw_intervals = STEEMIT_VESTING_WITHDRAW_INTERVALS_PRE_HF_16; - if( db().has_hardfork( STEEMIT_HARDFORK_0_16__551 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_16__551 ) ) vesting_withdraw_intervals = STEEMIT_VESTING_WITHDRAW_INTERVALS; /// 13 weeks = 1 quarter of a year - db().modify( account, [&]( account_object& a ) + _db.modify( account, [&]( account_object& a ) { auto new_vesting_withdraw_rate = asset( o.vesting_shares.amount / vesting_withdraw_intervals, VESTS_SYMBOL ); if( new_vesting_withdraw_rate.amount == 0 ) new_vesting_withdraw_rate.amount = 1; - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_5__57 ) ) + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_5__57 ) ) FC_ASSERT( account.vesting_withdraw_rate != new_vesting_withdraw_rate, "This operation would not change the vesting withdraw rate." ); a.vesting_withdraw_rate = new_vesting_withdraw_rate; - a.next_vesting_withdrawal = db().head_block_time() + fc::seconds(STEEMIT_VESTING_WITHDRAW_INTERVAL_SECONDS); + a.next_vesting_withdrawal = _db.head_block_time() + fc::seconds(STEEMIT_VESTING_WITHDRAW_INTERVAL_SECONDS); a.to_withdraw = o.vesting_shares.amount; a.withdrawn = 0; }); @@ -808,9 +826,10 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ { try { - const auto& from_account = db().get_account( o.from_account ); - const auto& to_account = db().get_account( o.to_account ); - const auto& wd_idx = db().get_index< withdraw_vesting_route_index >().indices().get< by_withdraw_route >(); + database& _db = db(); + const auto& from_account = _db.get_account( o.from_account ); + const auto& to_account = _db.get_account( o.to_account ); + const auto& wd_idx = _db.get_index< withdraw_vesting_route_index >().indices().get< by_withdraw_route >(); auto itr = wd_idx.find( boost::make_tuple( from_account.id, to_account.id ) ); if( itr == wd_idx.end() ) @@ -818,7 +837,7 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ FC_ASSERT( o.percent != 0, "Cannot create a 0% destination." ); FC_ASSERT( from_account.withdraw_routes < STEEMIT_MAX_WITHDRAW_ROUTES, "Account already has the maximum number of routes." ); - db().create< withdraw_vesting_route_object >( [&]( withdraw_vesting_route_object& wvdo ) + _db.create< withdraw_vesting_route_object >( [&]( withdraw_vesting_route_object& wvdo ) { wvdo.from_account = from_account.id; wvdo.to_account = to_account.id; @@ -826,23 +845,23 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ wvdo.auto_vest = o.auto_vest; }); - db().modify( from_account, [&]( account_object& a ) + _db.modify( from_account, [&]( account_object& a ) { a.withdraw_routes++; }); } else if( o.percent == 0 ) { - db().remove( *itr ); + _db.remove( *itr ); - db().modify( from_account, [&]( account_object& a ) + _db.modify( from_account, [&]( account_object& a ) { a.withdraw_routes--; }); } else { - db().modify( *itr, [&]( withdraw_vesting_route_object& wvdo ) + _db.modify( *itr, [&]( withdraw_vesting_route_object& wvdo ) { wvdo.from_account = from_account.id; wvdo.to_account = to_account.id; @@ -867,7 +886,8 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ void account_witness_proxy_evaluator::do_apply( const account_witness_proxy_operation& o ) { - const auto& account = db().get_account( o.account ); + database& _db = db(); + const auto& account = _db.get_account( o.account ); FC_ASSERT( account.proxy != o.proxy, "Proxy must change." ); FC_ASSERT( account.can_vote, "Account has declined the ability to vote and cannot proxy votes." ); @@ -877,35 +897,35 @@ void account_witness_proxy_evaluator::do_apply( const account_witness_proxy_oper delta[0] = -account.vesting_shares.amount; for( int i = 0; i < STEEMIT_MAX_PROXY_RECURSION_DEPTH; ++i ) delta[i+1] = -account.proxied_vsf_votes[i]; - db().adjust_proxied_witness_votes( account, delta ); + _db.adjust_proxied_witness_votes( account, delta ); if( o.proxy.size() ) { - const auto& new_proxy = db().get_account( o.proxy ); + const auto& new_proxy = _db.get_account( o.proxy ); flat_set proxy_chain( { account.id, new_proxy.id } ); proxy_chain.reserve( STEEMIT_MAX_PROXY_RECURSION_DEPTH + 1 ); /// check for proxy loops and fail to update the proxy if it would create a loop auto cprox = &new_proxy; while( cprox->proxy.size() != 0 ) { - const auto next_proxy = db().get_account( cprox->proxy ); + const auto next_proxy = _db.get_account( cprox->proxy ); FC_ASSERT( proxy_chain.insert( next_proxy.id ).second, "This proxy would create a proxy loop." ); cprox = &next_proxy; FC_ASSERT( proxy_chain.size() <= STEEMIT_MAX_PROXY_RECURSION_DEPTH, "Proxy chain is too long." ); } /// clear all individual vote records - db().clear_witness_votes( account ); + _db.clear_witness_votes( account ); - db().modify( account, [&]( account_object& a ) { + _db.modify( account, [&]( account_object& a ) { a.proxy = o.proxy; }); /// add all new votes for( int i = 0; i <= STEEMIT_MAX_PROXY_RECURSION_DEPTH; ++i ) delta[i] = -delta[i]; - db().adjust_proxied_witness_votes( account, delta ); + _db.adjust_proxied_witness_votes( account, delta ); } else { /// we are clearing the proxy which means we simply update the account - db().modify( account, [&]( account_object& a ) { + _db.modify( account, [&]( account_object& a ) { a.proxy = o.proxy; }); } @@ -914,114 +934,116 @@ void account_witness_proxy_evaluator::do_apply( const account_witness_proxy_oper void account_witness_vote_evaluator::do_apply( const account_witness_vote_operation& o ) { - const auto& voter = db().get_account( o.account ); + database& _db = db(); + const auto& voter = _db.get_account( o.account ); FC_ASSERT( voter.proxy.size() == 0, "A proxy is currently set, please clear the proxy before voting for a witness." ); if( o.approve ) FC_ASSERT( voter.can_vote, "Account has declined its voting rights." ); - const auto& witness = db().get_witness( o.witness ); + const auto& witness = _db.get_witness( o.witness ); - const auto& by_account_witness_idx = db().get_index< witness_vote_index >().indices().get< by_account_witness >(); + const auto& by_account_witness_idx = _db.get_index< witness_vote_index >().indices().get< by_account_witness >(); auto itr = by_account_witness_idx.find( boost::make_tuple( voter.id, witness.id ) ); if( itr == by_account_witness_idx.end() ) { FC_ASSERT( o.approve, "Vote doesn't exist, user must indicate a desire to approve witness." ); - if ( db().has_hardfork( STEEMIT_HARDFORK_0_2 ) ) + if ( _db.has_hardfork( STEEMIT_HARDFORK_0_2 ) ) { FC_ASSERT( voter.witnesses_voted_for < STEEMIT_MAX_ACCOUNT_WITNESS_VOTES, "Account has voted for too many witnesses." ); // TODO: Remove after hardfork 2 - db().create( [&]( witness_vote_object& v ) { + _db.create( [&]( witness_vote_object& v ) { v.witness = witness.id; v.account = voter.id; }); - if( db().has_hardfork( STEEMIT_HARDFORK_0_3 ) ) { - db().adjust_witness_vote( witness, voter.witness_vote_weight() ); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_3 ) ) { + _db.adjust_witness_vote( witness, voter.witness_vote_weight() ); } else { - db().adjust_proxied_witness_votes( voter, voter.witness_vote_weight() ); + _db.adjust_proxied_witness_votes( voter, voter.witness_vote_weight() ); } } else { - db().create( [&]( witness_vote_object& v ) { + _db.create( [&]( witness_vote_object& v ) { v.witness = witness.id; v.account = voter.id; }); - db().modify( witness, [&]( witness_object& w ) { + _db.modify( witness, [&]( witness_object& w ) { w.votes += voter.witness_vote_weight(); }); } - db().modify( voter, [&]( account_object& a ) { + _db.modify( voter, [&]( account_object& a ) { a.witnesses_voted_for++; }); } else { FC_ASSERT( !o.approve, "Vote currently exists, user must indicate a desire to reject witness." ); - if ( db().has_hardfork( STEEMIT_HARDFORK_0_2 ) ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_3 ) ) - db().adjust_witness_vote( witness, -voter.witness_vote_weight() ); + if ( _db.has_hardfork( STEEMIT_HARDFORK_0_2 ) ) { + if( _db.has_hardfork( STEEMIT_HARDFORK_0_3 ) ) + _db.adjust_witness_vote( witness, -voter.witness_vote_weight() ); else - db().adjust_proxied_witness_votes( voter, -voter.witness_vote_weight() ); + _db.adjust_proxied_witness_votes( voter, -voter.witness_vote_weight() ); } else { - db().modify( witness, [&]( witness_object& w ) { + _db.modify( witness, [&]( witness_object& w ) { w.votes -= voter.witness_vote_weight(); }); } - db().modify( voter, [&]( account_object& a ) { + _db.modify( voter, [&]( account_object& a ) { a.witnesses_voted_for--; }); - db().remove( *itr ); + _db.remove( *itr ); } } void vote_evaluator::do_apply( const vote_operation& o ) { try { + database& _db = db(); - const auto& comment = db().get_comment( o.author, o.permlink ); - const auto& voter = db().get_account( o.voter ); + const auto& comment = _db.get_comment( o.author, o.permlink ); + const auto& voter = _db.get_account( o.voter ); - if( db().has_hardfork( STEEMIT_HARDFORK_0_10 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_10 ) ) FC_ASSERT( !(voter.owner_challenged || voter.active_challenged ), "Operation cannot be processed because the account is currently challenged." ); FC_ASSERT( voter.can_vote, "Voter has declined their voting rights." ); if( o.weight > 0 ) FC_ASSERT( comment.allow_votes, "Votes are not allowed on the comment." ); - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && db().calculate_discussion_payout_time( comment ) == fc::time_point_sec::maximum() ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && _db.calculate_discussion_payout_time( comment ) == fc::time_point_sec::maximum() ) { #ifndef CLEAR_VOTES - const auto& comment_vote_idx = db().get_index< comment_vote_index >().indices().get< by_comment_voter >(); + const auto& comment_vote_idx = _db.get_index< comment_vote_index >().indices().get< by_comment_voter >(); auto itr = comment_vote_idx.find( std::make_tuple( comment.id, voter.id ) ); if( itr == comment_vote_idx.end() ) - db().create< comment_vote_object >( [&]( comment_vote_object& cvo ) + _db.create< comment_vote_object >( [&]( comment_vote_object& cvo ) { cvo.voter = voter.id; cvo.comment = comment.id; cvo.vote_percent = o.weight; - cvo.last_update = db().head_block_time(); + cvo.last_update = _db.head_block_time(); }); else - db().modify( *itr, [&]( comment_vote_object& cvo ) + _db.modify( *itr, [&]( comment_vote_object& cvo ) { cvo.vote_percent = o.weight; - cvo.last_update = db().head_block_time(); + cvo.last_update = _db.head_block_time(); }); #endif return; } - const auto& comment_vote_idx = db().get_index< comment_vote_index >().indices().get< by_comment_voter >(); + const auto& comment_vote_idx = _db.get_index< comment_vote_index >().indices().get< by_comment_voter >(); auto itr = comment_vote_idx.find( std::make_tuple( comment.id, voter.id ) ); - int64_t elapsed_seconds = (db().head_block_time() - voter.last_vote_time).to_seconds(); + int64_t elapsed_seconds = (_db.head_block_time() - voter.last_vote_time).to_seconds(); - if( db().has_hardfork( STEEMIT_HARDFORK_0_11 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_11 ) ) FC_ASSERT( elapsed_seconds >= STEEMIT_MIN_VOTE_INTERVAL_SEC, "Can only vote once every 3 seconds." ); int64_t regenerated_power = (STEEMIT_100_PERCENT * elapsed_seconds) / STEEMIT_VOTE_REGENERATION_SECONDS; @@ -1031,14 +1053,14 @@ void vote_evaluator::do_apply( const vote_operation& o ) int64_t abs_weight = abs(o.weight); int64_t used_power = (current_power * abs_weight) / STEEMIT_100_PERCENT; - const dynamic_global_property_object& dgpo = db().get_dynamic_global_properties(); + const dynamic_global_property_object& dgpo = _db.get_dynamic_global_properties(); // used_power = (current_power * abs_weight / STEEMIT_100_PERCENT) * (reserve / max_vote_denom) // The second multiplication is rounded up as of HF 259 int64_t max_vote_denom = dgpo.vote_regeneration_per_day * STEEMIT_VOTE_REGENERATION_SECONDS / (60*60*24); FC_ASSERT( max_vote_denom > 0 ); - if( !db().has_hardfork( STEEMIT_HARDFORK_0_14__259 ) ) + if( !_db.has_hardfork( STEEMIT_HARDFORK_0_14__259 ) ) { FC_ASSERT( max_vote_denom == 200 ); // TODO: Remove this assert used_power = (used_power / max_vote_denom)+1; @@ -1050,13 +1072,13 @@ void vote_evaluator::do_apply( const vote_operation& o ) FC_ASSERT( used_power <= current_power, "Account does not have enough power to vote." ); int64_t abs_rshares = ((uint128_t(voter.vesting_shares.amount.value) * used_power) / (STEEMIT_100_PERCENT)).to_uint64(); - if( !db().has_hardfork( STEEMIT_HARDFORK_0_14__259 ) && abs_rshares == 0 ) abs_rshares = 1; + if( !_db.has_hardfork( STEEMIT_HARDFORK_0_14__259 ) && abs_rshares == 0 ) abs_rshares = 1; - if( db().has_hardfork( STEEMIT_HARDFORK_0_14__259 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_14__259 ) ) { FC_ASSERT( abs_rshares > 50000000 || o.weight == 0, "Voting weight is too small, please accumulate more voting power or steem power." ); } - else if( db().has_hardfork( STEEMIT_HARDFORK_0_13__248 ) ) + else if( _db.has_hardfork( STEEMIT_HARDFORK_0_13__248 ) ) { FC_ASSERT( abs_rshares > 50000000 || abs_rshares == 1, "Voting weight is too small, please accumulate more voting power or steem power." ); } @@ -1066,10 +1088,10 @@ void vote_evaluator::do_apply( const vote_operation& o ) // Lazily delete vote if( itr != comment_vote_idx.end() && itr->num_changes == -1 ) { - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) ) + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) ) FC_ASSERT( false, "Cannot vote again on a comment after payout." ); - db().remove( *itr ); + _db.remove( *itr ); itr = comment_vote_idx.end(); } @@ -1079,31 +1101,31 @@ void vote_evaluator::do_apply( const vote_operation& o ) /// this is the rshares voting for or against the post int64_t rshares = o.weight < 0 ? -abs_rshares : abs_rshares; - if( rshares > 0 && db().has_hardfork( STEEMIT_HARDFORK_0_7 ) ) + if( rshares > 0 && _db.has_hardfork( STEEMIT_HARDFORK_0_7 ) ) { - FC_ASSERT( db().head_block_time() < db().calculate_discussion_payout_time( comment ) - STEEMIT_UPVOTE_LOCKOUT, "Cannot increase reward of post within the last minute before payout." ); + FC_ASSERT( _db.head_block_time() < _db.calculate_discussion_payout_time( comment ) - STEEMIT_UPVOTE_LOCKOUT, "Cannot increase reward of post within the last minute before payout." ); } //used_power /= (50*7); /// a 100% vote means use .28% of voting power which should force users to spread their votes around over 50+ posts day for a week //if( used_power == 0 ) used_power = 1; - db().modify( voter, [&]( account_object& a ){ + _db.modify( voter, [&]( account_object& a ){ a.voting_power = current_power - used_power; - a.last_vote_time = db().head_block_time(); + a.last_vote_time = _db.head_block_time(); }); /// if the current net_rshares is less than 0, the post is getting 0 rewards so it is not factored into total rshares^2 fc::uint128_t old_rshares = std::max(comment.net_rshares.value, int64_t(0)); - const auto& root = comment.root_comment( db() ); + const auto& root = comment.root_comment( _db ); auto old_root_abs_rshares = root.children_abs_rshares.value; - fc::uint128_t cur_cashout_time_sec = db().calculate_discussion_payout_time( comment ).sec_since_epoch(); + fc::uint128_t cur_cashout_time_sec = _db.calculate_discussion_payout_time( comment ).sec_since_epoch(); fc::uint128_t new_cashout_time_sec; - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && !db().has_hardfork( STEEMIT_HARDFORK_0_13__257) ) - new_cashout_time_sec = db().head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS; + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && !_db.has_hardfork( STEEMIT_HARDFORK_0_13__257) ) + new_cashout_time_sec = _db.head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS; else - new_cashout_time_sec = db().head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS_PRE_HF12; + new_cashout_time_sec = _db.head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS_PRE_HF12; auto avg_cashout_sec = ( cur_cashout_time_sec * old_root_abs_rshares + new_cashout_time_sec * abs_rshares ) / ( old_root_abs_rshares + abs_rshares ); @@ -1111,7 +1133,7 @@ void vote_evaluator::do_apply( const vote_operation& o ) auto old_vote_rshares = comment.vote_rshares; - db().modify( comment, [&]( comment_object& c ){ + _db.modify( comment, [&]( comment_object& c ){ c.net_rshares += rshares; c.abs_rshares += abs_rshares; if( rshares > 0 ) @@ -1120,31 +1142,31 @@ void vote_evaluator::do_apply( const vote_operation& o ) c.net_votes++; else c.net_votes--; - if( !db().has_hardfork( STEEMIT_HARDFORK_0_6__114 ) && c.net_rshares == -c.abs_rshares) FC_ASSERT( c.net_votes < 0, "Comment has negative net votes?" ); + if( !_db.has_hardfork( STEEMIT_HARDFORK_0_6__114 ) && c.net_rshares == -c.abs_rshares) FC_ASSERT( c.net_votes < 0, "Comment has negative net votes?" ); }); - db().modify( root, [&]( comment_object& c ) + _db.modify( root, [&]( comment_object& c ) { c.children_abs_rshares += abs_rshares; - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && c.last_payout > fc::time_point_sec::min() ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && c.last_payout > fc::time_point_sec::min() ) c.cashout_time = c.last_payout + STEEMIT_SECOND_CASHOUT_WINDOW; else c.cashout_time = fc::time_point_sec( std::min( uint32_t( avg_cashout_sec.to_uint64() ), c.max_cashout_time.sec_since_epoch() ) ); if( c.max_cashout_time == fc::time_point_sec::maximum() ) - c.max_cashout_time = db().head_block_time() + fc::seconds( STEEMIT_MAX_CASHOUT_WINDOW_SECONDS ); + c.max_cashout_time = _db.head_block_time() + fc::seconds( STEEMIT_MAX_CASHOUT_WINDOW_SECONDS ); }); fc::uint128_t new_rshares = std::max( comment.net_rshares.value, int64_t(0)); /// calculate rshares2 value - new_rshares = db().calculate_vshares( new_rshares ); - old_rshares = db().calculate_vshares( old_rshares ); + new_rshares = _db.calculate_vshares( new_rshares ); + old_rshares = _db.calculate_vshares( old_rshares ); - const auto& cat = db().get_category( comment.category ); - db().modify( cat, [&]( category_object& c ){ + const auto& cat = _db.get_category( comment.category ); + _db.modify( cat, [&]( category_object& c ){ c.abs_rshares += abs_rshares; - c.last_update = db().head_block_time(); + c.last_update = _db.head_block_time(); }); uint64_t max_vote_weight = 0; @@ -1167,12 +1189,12 @@ void vote_evaluator::do_apply( const vote_operation& o ) * Since W(R_0) = 0, c.total_vote_weight is also bounded above by B and will always fit in a 64 bit integer. * **/ - db().create( [&]( comment_vote_object& cv ){ + _db.create( [&]( comment_vote_object& cv ){ cv.voter = voter.id; cv.comment = comment.id; cv.rshares = rshares; cv.vote_percent = o.weight; - cv.last_update = db().head_block_time(); + cv.last_update = _db.head_block_time(); if( rshares > 0 && (comment.last_payout == fc::time_point_sec()) && comment.allow_curation_rewards ) { @@ -1180,7 +1202,7 @@ void vote_evaluator::do_apply( const vote_operation& o ) u512 rshares3(rshares); u256 total2( comment.abs_rshares.value ); - if( !db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) + if( !_db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { rshares3 *= 1000000; total2 *= 1000000; @@ -1191,23 +1213,23 @@ void vote_evaluator::do_apply( const vote_operation& o ) total2 *= total2; cv.weight = static_cast( rshares3 / total2 ); } else {// cv.weight = W(R_1) - W(R_0) - if( db().has_hardfork( STEEMIT_HARDFORK_0_1 ) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ) { - uint64_t old_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( old_vote_rshares.value ) ) / ( 2 * db().get_content_constant_s() + old_vote_rshares.value ) ).to_uint64(); - uint64_t new_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( comment.vote_rshares.value ) ) / ( 2 * db().get_content_constant_s() + comment.vote_rshares.value ) ).to_uint64(); + uint64_t old_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( old_vote_rshares.value ) ) / ( 2 * _db.get_content_constant_s() + old_vote_rshares.value ) ).to_uint64(); + uint64_t new_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( comment.vote_rshares.value ) ) / ( 2 * _db.get_content_constant_s() + comment.vote_rshares.value ) ).to_uint64(); cv.weight = new_weight - old_weight; } else { - uint64_t old_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( 1000000 * old_vote_rshares.value ) ) / ( 2 * db().get_content_constant_s() + ( 1000000 * old_vote_rshares.value ) ) ).to_uint64(); - uint64_t new_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( 1000000 * comment.vote_rshares.value ) ) / ( 2 * db().get_content_constant_s() + ( 1000000 * comment.vote_rshares.value ) ) ).to_uint64(); + uint64_t old_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( 1000000 * old_vote_rshares.value ) ) / ( 2 * _db.get_content_constant_s() + ( 1000000 * old_vote_rshares.value ) ) ).to_uint64(); + uint64_t new_weight = ( ( std::numeric_limits< uint64_t >::max() * fc::uint128_t( 1000000 * comment.vote_rshares.value ) ) / ( 2 * _db.get_content_constant_s() + ( 1000000 * comment.vote_rshares.value ) ) ).to_uint64(); cv.weight = new_weight - old_weight; } } max_vote_weight = cv.weight; - if( db().head_block_time() > fc::time_point_sec(STEEMIT_HARDFORK_0_6_REVERSE_AUCTION_TIME) ) /// start enforcing this prior to the hardfork + if( _db.head_block_time() > fc::time_point_sec(STEEMIT_HARDFORK_0_6_REVERSE_AUCTION_TIME) ) /// start enforcing this prior to the hardfork { /// discount weight by time uint128_t w(max_vote_weight); @@ -1226,52 +1248,52 @@ void vote_evaluator::do_apply( const vote_operation& o ) if( max_vote_weight ) // Optimization { - db().modify( comment, [&]( comment_object& c ) + _db.modify( comment, [&]( comment_object& c ) { c.total_vote_weight += max_vote_weight; }); } - db().adjust_rshares2( comment, old_rshares, new_rshares ); + _db.adjust_rshares2( comment, old_rshares, new_rshares ); } else { FC_ASSERT( itr->num_changes < STEEMIT_MAX_VOTE_CHANGES, "Voter has used the maximum number of vote changes on this comment." ); - if( db().is_producing() || db().has_hardfork( STEEMIT_HARDFORK_0_6__112 ) ) + if( _db.is_producing() || _db.has_hardfork( STEEMIT_HARDFORK_0_6__112 ) ) FC_ASSERT( itr->vote_percent != o.weight, "You have already voted in a similar way." ); /// this is the rshares voting for or against the post int64_t rshares = o.weight < 0 ? -abs_rshares : abs_rshares; - if( itr->rshares < rshares && db().has_hardfork( STEEMIT_HARDFORK_0_7 ) ) - FC_ASSERT( db().head_block_time() < db().calculate_discussion_payout_time( comment ) - STEEMIT_UPVOTE_LOCKOUT, "Cannot increase payout within last minute before payout." ); + if( itr->rshares < rshares && _db.has_hardfork( STEEMIT_HARDFORK_0_7 ) ) + FC_ASSERT( _db.head_block_time() < _db.calculate_discussion_payout_time( comment ) - STEEMIT_UPVOTE_LOCKOUT, "Cannot increase payout within last minute before payout." ); - db().modify( voter, [&]( account_object& a ){ + _db.modify( voter, [&]( account_object& a ){ a.voting_power = current_power - used_power; - a.last_vote_time = db().head_block_time(); + a.last_vote_time = _db.head_block_time(); }); /// if the current net_rshares is less than 0, the post is getting 0 rewards so it is not factored into total rshares^2 fc::uint128_t old_rshares = std::max(comment.net_rshares.value, int64_t(0)); - const auto& root = comment.root_comment( db() ); + const auto& root = comment.root_comment( _db ); auto old_root_abs_rshares = root.children_abs_rshares.value; - fc::uint128_t cur_cashout_time_sec = db().calculate_discussion_payout_time( comment ).sec_since_epoch(); + fc::uint128_t cur_cashout_time_sec = _db.calculate_discussion_payout_time( comment ).sec_since_epoch(); fc::uint128_t new_cashout_time_sec; - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && ! db().has_hardfork( STEEMIT_HARDFORK_0_13__257 ) ) - new_cashout_time_sec = db().head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS; + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && ! _db.has_hardfork( STEEMIT_HARDFORK_0_13__257 ) ) + new_cashout_time_sec = _db.head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS; else - new_cashout_time_sec = db().head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS_PRE_HF12; + new_cashout_time_sec = _db.head_block_time().sec_since_epoch() + STEEMIT_CASHOUT_WINDOW_SECONDS_PRE_HF12; fc::uint128_t avg_cashout_sec; - if( db().has_hardfork( STEEMIT_HARDFORK_0_14__259 ) && abs_rshares == 0 ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_14__259 ) && abs_rshares == 0 ) avg_cashout_sec = cur_cashout_time_sec; else avg_cashout_sec = ( cur_cashout_time_sec * old_root_abs_rshares + new_cashout_time_sec * abs_rshares ) / ( old_root_abs_rshares + abs_rshares ); - db().modify( comment, [&]( comment_object& c ) + _db.modify( comment, [&]( comment_object& c ) { c.net_rshares -= itr->rshares; c.net_rshares += rshares; @@ -1292,39 +1314,39 @@ void vote_evaluator::do_apply( const vote_operation& o ) c.net_votes -= 2; }); - db().modify( root, [&]( comment_object& c ) + _db.modify( root, [&]( comment_object& c ) { c.children_abs_rshares += abs_rshares; - if( db().has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && c.last_payout > fc::time_point_sec::min() ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177 ) && c.last_payout > fc::time_point_sec::min() ) c.cashout_time = c.last_payout + STEEMIT_SECOND_CASHOUT_WINDOW; else c.cashout_time = fc::time_point_sec( std::min( uint32_t( avg_cashout_sec.to_uint64() ), c.max_cashout_time.sec_since_epoch() ) ); if( c.max_cashout_time == fc::time_point_sec::maximum() ) - c.max_cashout_time = db().head_block_time() + fc::seconds( STEEMIT_MAX_CASHOUT_WINDOW_SECONDS ); + c.max_cashout_time = _db.head_block_time() + fc::seconds( STEEMIT_MAX_CASHOUT_WINDOW_SECONDS ); }); fc::uint128_t new_rshares = std::max( comment.net_rshares.value, int64_t(0)); /// calculate rshares2 value - new_rshares = db().calculate_vshares( new_rshares ); - old_rshares = db().calculate_vshares( old_rshares ); + new_rshares = _db.calculate_vshares( new_rshares ); + old_rshares = _db.calculate_vshares( old_rshares ); - db().modify( comment, [&]( comment_object& c ) + _db.modify( comment, [&]( comment_object& c ) { c.total_vote_weight -= itr->weight; }); - db().modify( *itr, [&]( comment_vote_object& cv ) + _db.modify( *itr, [&]( comment_vote_object& cv ) { cv.rshares = rshares; cv.vote_percent = o.weight; - cv.last_update = db().head_block_time(); + cv.last_update = _db.head_block_time(); cv.weight = 0; cv.num_changes += 1; }); - db().adjust_rshares2( comment, old_rshares, new_rshares ); + _db.adjust_rshares2( comment, old_rshares, new_rshares ); } } FC_CAPTURE_AND_RETHROW( (o)) } @@ -1356,9 +1378,9 @@ void custom_json_evaluator::do_apply( const custom_json_operation& o ) void custom_binary_evaluator::do_apply( const custom_binary_operation& o ) { - FC_ASSERT( db().has_hardfork( STEEMIT_HARDFORK_0_14__317 ) ); - database& d = db(); + FC_ASSERT( d.has_hardfork( STEEMIT_HARDFORK_0_14__317 ) ); + std::shared_ptr< custom_operation_interpreter > eval = d.get_custom_json_evaluator( o.id ); if( !eval ) return; @@ -1568,50 +1590,53 @@ void pow2_evaluator::do_apply( const pow2_operation& o ) void feed_publish_evaluator::do_apply( const feed_publish_operation& o ) { - const auto& witness = db().get_witness( o.publisher ); - db().modify( witness, [&]( witness_object& w ){ + database& _db = db(); + const auto& witness = _db.get_witness( o.publisher ); + _db.modify( witness, [&]( witness_object& w ){ w.sbd_exchange_rate = o.exchange_rate; - w.last_sbd_exchange_update = db().head_block_time(); + w.last_sbd_exchange_update = _db.head_block_time(); }); } void convert_evaluator::do_apply( const convert_operation& o ) { - const auto& owner = db().get_account( o.owner ); - FC_ASSERT( db().get_balance( owner, o.amount.symbol ) >= o.amount, "Account does not have sufficient balance for conversion." ); + database& _db = db(); + const auto& owner = _db.get_account( o.owner ); + FC_ASSERT( _db.get_balance( owner, o.amount.symbol ) >= o.amount, "Account does not have sufficient balance for conversion." ); - db().adjust_balance( owner, -o.amount ); + _db.adjust_balance( owner, -o.amount ); - const auto& fhistory = db().get_feed_history(); + const auto& fhistory = _db.get_feed_history(); FC_ASSERT( !fhistory.current_median_history.is_null(), "Cannot convert SBD because there is no price feed." ); auto steemit_conversion_delay = STEEMIT_CONVERSION_DELAY_PRE_HF_16; - if( db().has_hardfork( STEEMIT_HARDFORK_0_16__551) ) + if( _db.has_hardfork( STEEMIT_HARDFORK_0_16__551) ) steemit_conversion_delay = STEEMIT_CONVERSION_DELAY; - db().create( [&]( convert_request_object& obj ) + _db.create( [&]( convert_request_object& obj ) { obj.owner = o.owner; obj.requestid = o.requestid; obj.amount = o.amount; - obj.conversion_date = db().head_block_time() + steemit_conversion_delay; + obj.conversion_date = _db.head_block_time() + steemit_conversion_delay; }); } void limit_order_create_evaluator::do_apply( const limit_order_create_operation& o ) { - FC_ASSERT( o.expiration > db().head_block_time(), "Limit order has to expire after head block time." ); + database& _db = db(); + FC_ASSERT( o.expiration > _db.head_block_time(), "Limit order has to expire after head block time." ); - const auto& owner = db().get_account( o.owner ); + const auto& owner = _db.get_account( o.owner ); - FC_ASSERT( db().get_balance( owner, o.amount_to_sell.symbol ) >= o.amount_to_sell, "Account does not have sufficient funds for limit order." ); + FC_ASSERT( _db.get_balance( owner, o.amount_to_sell.symbol ) >= o.amount_to_sell, "Account does not have sufficient funds for limit order." ); - db().adjust_balance( owner, -o.amount_to_sell ); + _db.adjust_balance( owner, -o.amount_to_sell ); - const auto& order = db().create( [&]( limit_order_object& obj ) + const auto& order = _db.create( [&]( limit_order_object& obj ) { - obj.created = db().head_block_time(); + obj.created = _db.head_block_time(); obj.seller = o.owner; obj.orderid = o.orderid; obj.for_sale = o.amount_to_sell.amount; @@ -1619,24 +1644,25 @@ void limit_order_create_evaluator::do_apply( const limit_order_create_operation& obj.expiration = o.expiration; }); - bool filled = db().apply_order( order ); + bool filled = _db.apply_order( order ); if( o.fill_or_kill ) FC_ASSERT( filled, "Cancelling order because it was not filled." ); } void limit_order_create2_evaluator::do_apply( const limit_order_create2_operation& o ) { - FC_ASSERT( o.expiration > db().head_block_time(), "Limit order has to expire after head block time." ); + database& _db = db(); + FC_ASSERT( o.expiration > _db.head_block_time(), "Limit order has to expire after head block time." ); - const auto& owner = db().get_account( o.owner ); + const auto& owner = _db.get_account( o.owner ); - FC_ASSERT( db().get_balance( owner, o.amount_to_sell.symbol ) >= o.amount_to_sell, "Account does not have sufficient funds for limit order." ); + FC_ASSERT( _db.get_balance( owner, o.amount_to_sell.symbol ) >= o.amount_to_sell, "Account does not have sufficient funds for limit order." ); - db().adjust_balance( owner, -o.amount_to_sell ); + _db.adjust_balance( owner, -o.amount_to_sell ); - const auto& order = db().create( [&]( limit_order_object& obj ) + const auto& order = _db.create( [&]( limit_order_object& obj ) { - obj.created = db().head_block_time(); + obj.created = _db.head_block_time(); obj.seller = o.owner; obj.orderid = o.orderid; obj.for_sale = o.amount_to_sell.amount; @@ -1644,38 +1670,41 @@ void limit_order_create2_evaluator::do_apply( const limit_order_create2_operatio obj.expiration = o.expiration; }); - bool filled = db().apply_order( order ); + bool filled = _db.apply_order( order ); if( o.fill_or_kill ) FC_ASSERT( filled, "Cancelling order because it was not filled." ); } void limit_order_cancel_evaluator::do_apply( const limit_order_cancel_operation& o ) { - db().cancel_order( db().get_limit_order( o.owner, o.orderid ) ); + database& _db = db(); + _db.cancel_order( _db.get_limit_order( o.owner, o.orderid ) ); } void report_over_production_evaluator::do_apply( const report_over_production_operation& o ) { - FC_ASSERT( !db().has_hardfork( STEEMIT_HARDFORK_0_4 ), "report_over_production_operation is disabled." ); + database& _db = db(); + FC_ASSERT( !_db.has_hardfork( STEEMIT_HARDFORK_0_4 ), "report_over_production_operation is disabled." ); } void challenge_authority_evaluator::do_apply( const challenge_authority_operation& o ) { - if( db().has_hardfork( STEEMIT_HARDFORK_0_14__307 ) ) FC_ASSERT( false, "Challenge authority operation is currently disabled." ); - const auto& challenged = db().get_account( o.challenged ); - const auto& challenger = db().get_account( o.challenger ); + database& _db = db(); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_14__307 ) ) FC_ASSERT( false, "Challenge authority operation is currently disabled." ); + const auto& challenged = _db.get_account( o.challenged ); + const auto& challenger = _db.get_account( o.challenger ); if( o.require_owner ) { FC_ASSERT( challenged.reset_account == o.challenger, "Owner authority can only be challenged by its reset account." ); FC_ASSERT( challenger.balance >= STEEMIT_OWNER_CHALLENGE_FEE ); FC_ASSERT( !challenged.owner_challenged ); - FC_ASSERT( db().head_block_time() - challenged.last_owner_proved > STEEMIT_OWNER_CHALLENGE_COOLDOWN ); + FC_ASSERT( _db.head_block_time() - challenged.last_owner_proved > STEEMIT_OWNER_CHALLENGE_COOLDOWN ); - db().adjust_balance( challenger, - STEEMIT_OWNER_CHALLENGE_FEE ); - db().create_vesting( db().get_account( o.challenged ), STEEMIT_OWNER_CHALLENGE_FEE ); + _db.adjust_balance( challenger, - STEEMIT_OWNER_CHALLENGE_FEE ); + _db.create_vesting( _db.get_account( o.challenged ), STEEMIT_OWNER_CHALLENGE_FEE ); - db().modify( challenged, [&]( account_object& a ) + _db.modify( challenged, [&]( account_object& a ) { a.owner_challenged = true; }); @@ -1684,12 +1713,12 @@ void challenge_authority_evaluator::do_apply( const challenge_authority_operatio { FC_ASSERT( challenger.balance >= STEEMIT_ACTIVE_CHALLENGE_FEE, "Account does not have sufficient funds to pay challenge fee." ); FC_ASSERT( !( challenged.owner_challenged || challenged.active_challenged ), "Account is already challenged." ); - FC_ASSERT( db().head_block_time() - challenged.last_active_proved > STEEMIT_ACTIVE_CHALLENGE_COOLDOWN, "Account cannot be challenged because it was recently challenged." ); + FC_ASSERT( _db.head_block_time() - challenged.last_active_proved > STEEMIT_ACTIVE_CHALLENGE_COOLDOWN, "Account cannot be challenged because it was recently challenged." ); - db().adjust_balance( challenger, - STEEMIT_ACTIVE_CHALLENGE_FEE ); - db().create_vesting( db().get_account( o.challenged ), STEEMIT_ACTIVE_CHALLENGE_FEE ); + _db.adjust_balance( challenger, - STEEMIT_ACTIVE_CHALLENGE_FEE ); + _db.create_vesting( _db.get_account( o.challenged ), STEEMIT_ACTIVE_CHALLENGE_FEE ); - db().modify( challenged, [&]( account_object& a ) + _db.modify( challenged, [&]( account_object& a ) { a.active_challenged = true; }); @@ -1698,31 +1727,33 @@ void challenge_authority_evaluator::do_apply( const challenge_authority_operatio void prove_authority_evaluator::do_apply( const prove_authority_operation& o ) { - const auto& challenged = db().get_account( o.challenged ); + database& _db = db(); + const auto& challenged = _db.get_account( o.challenged ); FC_ASSERT( challenged.owner_challenged || challenged.active_challenged, "Account is not challeneged. No need to prove authority." ); - db().modify( challenged, [&]( account_object& a ) + _db.modify( challenged, [&]( account_object& a ) { a.active_challenged = false; - a.last_active_proved = db().head_block_time(); + a.last_active_proved = _db.head_block_time(); if( o.require_owner ) { a.owner_challenged = false; - a.last_owner_proved = db().head_block_time(); + a.last_owner_proved = _db.head_block_time(); } }); } void request_account_recovery_evaluator::do_apply( const request_account_recovery_operation& o ) { - const auto& account_to_recover = db().get_account( o.account_to_recover ); + database& _db = db(); + const auto& account_to_recover = _db.get_account( o.account_to_recover ); if ( account_to_recover.recovery_account.length() ) // Make sure recovery matches expected recovery account FC_ASSERT( account_to_recover.recovery_account == o.recovery_account, "Cannot recover an account that does not have you as there recovery partner." ); else // Empty string recovery account defaults to top witness - FC_ASSERT( db().get_index< witness_index >().indices().get< by_vote_name >().begin()->owner == o.recovery_account, "Top witness must recover an account with no recovery partner." ); + FC_ASSERT( _db.get_index< witness_index >().indices().get< by_vote_name >().begin()->owner == o.recovery_account, "Top witness must recover an account with no recovery partner." ); - const auto& recovery_request_idx = db().get_index< account_recovery_request_index >().indices().get< by_account >(); + const auto& recovery_request_idx = _db.get_index< account_recovery_request_index >().indices().get< by_account >(); auto request = recovery_request_idx.find( o.account_to_recover ); if( request == recovery_request_idx.end() ) // New Request @@ -1731,60 +1762,61 @@ void request_account_recovery_evaluator::do_apply( const request_account_recover FC_ASSERT( o.new_owner_authority.weight_threshold, "Cannot recover using an open authority." ); // Check accounts in the new authority exist - if( ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) ) + if( ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) ) { for( auto& a : o.new_owner_authority.account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - db().create< account_recovery_request_object >( [&]( account_recovery_request_object& req ) + _db.create< account_recovery_request_object >( [&]( account_recovery_request_object& req ) { req.account_to_recover = o.account_to_recover; req.new_owner_authority = o.new_owner_authority; - req.expires = db().head_block_time() + STEEMIT_ACCOUNT_RECOVERY_REQUEST_EXPIRATION_PERIOD; + req.expires = _db.head_block_time() + STEEMIT_ACCOUNT_RECOVERY_REQUEST_EXPIRATION_PERIOD; }); } else if( o.new_owner_authority.weight_threshold == 0 ) // Cancel Request if authority is open { - db().remove( *request ); + _db.remove( *request ); } else // Change Request { FC_ASSERT( !o.new_owner_authority.is_impossible(), "Cannot recover using an impossible authority." ); // Check accounts in the new authority exist - if( ( db().has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || db().is_producing() ) ) + if( ( _db.has_hardfork( STEEMIT_HARDFORK_0_15__465 ) || _db.is_producing() ) ) { for( auto& a : o.new_owner_authority.account_auths ) { - db().get_account( a.first ); + _db.get_account( a.first ); } } - db().modify( *request, [&]( account_recovery_request_object& req ) + _db.modify( *request, [&]( account_recovery_request_object& req ) { req.new_owner_authority = o.new_owner_authority; - req.expires = db().head_block_time() + STEEMIT_ACCOUNT_RECOVERY_REQUEST_EXPIRATION_PERIOD; + req.expires = _db.head_block_time() + STEEMIT_ACCOUNT_RECOVERY_REQUEST_EXPIRATION_PERIOD; }); } } void recover_account_evaluator::do_apply( const recover_account_operation& o ) { - const auto& account = db().get_account( o.account_to_recover ); + database& _db = db(); + const auto& account = _db.get_account( o.account_to_recover ); - if( db().has_hardfork( STEEMIT_HARDFORK_0_12 ) ) - FC_ASSERT( db().head_block_time() - account.last_account_recovery > STEEMIT_OWNER_UPDATE_LIMIT, "Owner authority can only be updated once an hour." ); + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12 ) ) + FC_ASSERT( _db.head_block_time() - account.last_account_recovery > STEEMIT_OWNER_UPDATE_LIMIT, "Owner authority can only be updated once an hour." ); - const auto& recovery_request_idx = db().get_index< account_recovery_request_index >().indices().get< by_account >(); + const auto& recovery_request_idx = _db.get_index< account_recovery_request_index >().indices().get< by_account >(); auto request = recovery_request_idx.find( o.account_to_recover ); FC_ASSERT( request != recovery_request_idx.end(), "There are no active recovery requests for this account." ); FC_ASSERT( request->new_owner_authority == o.new_owner_authority, "New owner authority does not match recovery request." ); - const auto& recent_auth_idx = db().get_index< owner_authority_history_index >().indices().get< by_account >(); + const auto& recent_auth_idx = _db.get_index< owner_authority_history_index >().indices().get< by_account >(); auto hist = recent_auth_idx.lower_bound( o.account_to_recover ); bool found = false; @@ -1797,65 +1829,68 @@ void recover_account_evaluator::do_apply( const recover_account_operation& o ) FC_ASSERT( found, "Recent authority not found in authority history." ); - db().remove( *request ); // Remove first, update_owner_authority may invalidate iterator - db().update_owner_authority( account, o.new_owner_authority ); - db().modify( account, [&]( account_object& a ) + _db.remove( *request ); // Remove first, update_owner_authority may invalidate iterator + _db.update_owner_authority( account, o.new_owner_authority ); + _db.modify( account, [&]( account_object& a ) { - a.last_account_recovery = db().head_block_time(); + a.last_account_recovery = _db.head_block_time(); }); } void change_recovery_account_evaluator::do_apply( const change_recovery_account_operation& o ) { - db().get_account( o.new_recovery_account ); // Simply validate account exists - const auto& account_to_recover = db().get_account( o.account_to_recover ); + database& _db = db(); + _db.get_account( o.new_recovery_account ); // Simply validate account exists + const auto& account_to_recover = _db.get_account( o.account_to_recover ); - const auto& change_recovery_idx = db().get_index< change_recovery_account_request_index >().indices().get< by_account >(); + const auto& change_recovery_idx = _db.get_index< change_recovery_account_request_index >().indices().get< by_account >(); auto request = change_recovery_idx.find( o.account_to_recover ); if( request == change_recovery_idx.end() ) // New request { - db().create< change_recovery_account_request_object >( [&]( change_recovery_account_request_object& req ) + _db.create< change_recovery_account_request_object >( [&]( change_recovery_account_request_object& req ) { req.account_to_recover = o.account_to_recover; req.recovery_account = o.new_recovery_account; - req.effective_on = db().head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; + req.effective_on = _db.head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; }); } else if( account_to_recover.recovery_account != o.new_recovery_account ) // Change existing request { - db().modify( *request, [&]( change_recovery_account_request_object& req ) + _db.modify( *request, [&]( change_recovery_account_request_object& req ) { req.recovery_account = o.new_recovery_account; - req.effective_on = db().head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; + req.effective_on = _db.head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; }); } else // Request exists and changing back to current recovery account { - db().remove( *request ); + _db.remove( *request ); } } void transfer_to_savings_evaluator::do_apply( const transfer_to_savings_operation& op ) { - const auto& from = db().get_account( op.from ); - const auto& to = db().get_account(op.to); - FC_ASSERT( db().get_balance( from, op.amount.symbol ) >= op.amount, "Account does not have sufficient funds to transfer to savings." ); + database& _db = db(); + const auto& from = _db.get_account( op.from ); + const auto& to = _db.get_account(op.to); + FC_ASSERT( _db.get_balance( from, op.amount.symbol ) >= op.amount, "Account does not have sufficient funds to transfer to savings." ); - db().adjust_balance( from, -op.amount ); - db().adjust_savings_balance( to, op.amount ); + _db.adjust_balance( from, -op.amount ); + _db.adjust_savings_balance( to, op.amount ); } void transfer_from_savings_evaluator::do_apply( const transfer_from_savings_operation& op ) { - const auto& from = db().get_account( op.from ); - db().get_account(op.to); // Verify to account exists + database& _db = db(); + const auto& from = _db.get_account( op.from ); + _db.get_account(op.to); // Verify to account exists FC_ASSERT( from.savings_withdraw_requests < STEEMIT_SAVINGS_WITHDRAW_REQUEST_LIMIT, "Account has reached limit for pending withdraw requests." ); - FC_ASSERT( db().get_savings_balance( from, op.amount.symbol ) >= op.amount ); - db().adjust_savings_balance( from, -op.amount ); - db().create( [&]( savings_withdraw_object& s ) { + FC_ASSERT( _db.get_savings_balance( from, op.amount.symbol ) >= op.amount ); + _db.adjust_savings_balance( from, -op.amount ); + _db.create( [&]( savings_withdraw_object& s ) { s.from = op.from; s.to = op.to; s.amount = op.amount; @@ -1863,10 +1898,10 @@ void transfer_from_savings_evaluator::do_apply( const transfer_from_savings_oper from_string( s.memo, op.memo ); #endif s.request_id = op.request_id; - s.complete = db().head_block_time() + STEEMIT_SAVINGS_WITHDRAW_TIME; + s.complete = _db.head_block_time() + STEEMIT_SAVINGS_WITHDRAW_TIME; }); - db().modify( from, [&]( account_object& a ) + _db.modify( from, [&]( account_object& a ) { a.savings_withdraw_requests++; }); @@ -1874,12 +1909,13 @@ void transfer_from_savings_evaluator::do_apply( const transfer_from_savings_oper void cancel_transfer_from_savings_evaluator::do_apply( const cancel_transfer_from_savings_operation& op ) { - const auto& swo = db().get_savings_withdraw( op.from, op.request_id ); - db().adjust_savings_balance( db().get_account( swo.from ), swo.amount ); - db().remove( swo ); + database& _db = db(); + const auto& swo = _db.get_savings_withdraw( op.from, op.request_id ); + _db.adjust_savings_balance( _db.get_account( swo.from ), swo.amount ); + _db.remove( swo ); - const auto& from = db().get_account( op.from ); - db().modify( from, [&]( account_object& a ) + const auto& from = _db.get_account( op.from ); + _db.modify( from, [&]( account_object& a ) { a.savings_withdraw_requests--; }); @@ -1887,51 +1923,54 @@ void cancel_transfer_from_savings_evaluator::do_apply( const cancel_transfer_fro void decline_voting_rights_evaluator::do_apply( const decline_voting_rights_operation& o ) { - FC_ASSERT( db().has_hardfork( STEEMIT_HARDFORK_0_14__324 ) ); + database& _db = db(); + FC_ASSERT( _db.has_hardfork( STEEMIT_HARDFORK_0_14__324 ) ); - const auto& account = db().get_account( o.account ); - const auto& request_idx = db().get_index< decline_voting_rights_request_index >().indices().get< by_account >(); + const auto& account = _db.get_account( o.account ); + const auto& request_idx = _db.get_index< decline_voting_rights_request_index >().indices().get< by_account >(); auto itr = request_idx.find( account.id ); if( o.decline ) { FC_ASSERT( itr == request_idx.end(), "Cannot create new request because one already exists." ); - db().create< decline_voting_rights_request_object >( [&]( decline_voting_rights_request_object& req ) + _db.create< decline_voting_rights_request_object >( [&]( decline_voting_rights_request_object& req ) { req.account = account.id; - req.effective_date = db().head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; + req.effective_date = _db.head_block_time() + STEEMIT_OWNER_AUTH_RECOVERY_PERIOD; }); } else { FC_ASSERT( itr != request_idx.end(), "Cannot cancel the request because it does not exist." ); - db().remove( *itr ); + _db.remove( *itr ); } } void reset_account_evaluator::do_apply( const reset_account_operation& op ) { + database& _db = db(); FC_ASSERT( false, "Reset Account Operation is currently disabled." ); - const auto& acnt = db().get_account( op.account_to_reset ); - FC_ASSERT( (db().head_block_time() - acnt.last_bandwidth_update) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); + const auto& acnt = _db.get_account( op.account_to_reset ); + FC_ASSERT( (_db.head_block_time() - acnt.last_bandwidth_update) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); FC_ASSERT( acnt.reset_account == op.reset_account, "Reset account does not match reset account on account." ); - db().update_owner_authority( acnt, op.new_owner_authority ); + _db.update_owner_authority( acnt, op.new_owner_authority ); } void set_reset_account_evaluator::do_apply( const set_reset_account_operation& op ) { + database& _db = db(); FC_ASSERT( false, "Set Reset Account Operation is currently disabled." ); - const auto& acnt = db().get_account( op.account ); - db().get_account( op.reset_account ); + const auto& acnt = _db.get_account( op.account ); + _db.get_account( op.reset_account ); FC_ASSERT( acnt.reset_account == op.current_reset_account, "Current reset account does not match reset account on account." ); FC_ASSERT( acnt.reset_account != op.reset_account, "Reset account must change" ); - db().modify( acnt, [&]( account_object& a ) + _db.modify( acnt, [&]( account_object& a ) { a.reset_account = op.reset_account; }); From b8d7fcda85b9cde359dd3831d30bb9ca6673d980 Mon Sep 17 00:00:00 2001 From: furion <_@furion.me> Date: Wed, 7 Dec 2016 20:06:04 +0100 Subject: [PATCH 22/77] fixed issue #676 - author_reward permlink is now a string --- .../include/steemit/protocol/steem_virtual_operations.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/protocol/include/steemit/protocol/steem_virtual_operations.hpp b/libraries/protocol/include/steemit/protocol/steem_virtual_operations.hpp index 7f0317bbf2..b88e2c8854 100644 --- a/libraries/protocol/include/steemit/protocol/steem_virtual_operations.hpp +++ b/libraries/protocol/include/steemit/protocol/steem_virtual_operations.hpp @@ -9,11 +9,11 @@ namespace steemit { namespace protocol { struct author_reward_operation : public virtual_operation { author_reward_operation(){} - author_reward_operation( const account_name_type& a, const account_name_type& p, const asset& s, const asset& st, const asset& v ) + author_reward_operation( const account_name_type& a, const string& p, const asset& s, const asset& st, const asset& v ) :author(a), permlink(p), sbd_payout(s), steem_payout(st), vesting_payout(v){} account_name_type author; - account_name_type permlink; + string permlink; asset sbd_payout; asset steem_payout; asset vesting_payout; From 4f197c65cfc7386b724841daaaec2aeeb4458057 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 8 Dec 2016 17:58:06 -0500 Subject: [PATCH 23/77] Remove deprecated id(db) syntax #687 --- libraries/app/database_api.cpp | 22 +++++++++---------- libraries/chain/database.cpp | 22 +++++++++---------- libraries/chain/steem_evaluator.cpp | 6 ++--- libraries/chainbase | 2 +- .../blockchain_statistics_api.cpp | 2 +- .../blockchain_statistics_plugin.cpp | 8 +++---- .../plugins/debug_node/debug_node_api.cpp | 7 +++--- libraries/plugins/follow/follow_api.cpp | 8 +++---- tests/common/database_fixture.cpp | 4 ++-- tests/tests/block_tests.cpp | 16 +++++++------- tests/tests/live_tests.cpp | 4 ++-- tests/tests/operation_time_tests.cpp | 2 +- 12 files changed, 51 insertions(+), 52 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 58e987b93e..d4017fb108 100755 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -309,7 +309,7 @@ witness_schedule_api_obj database_api::get_witness_schedule()const { return my->_db.with_read_lock( [&]() { - return witness_schedule_id_type()( my->_db ); + return my->_db.get(witness_schedule_id_type()); }); } @@ -317,7 +317,7 @@ hardfork_version database_api::get_hardfork_version()const { return my->_db.with_read_lock( [&]() { - return hardfork_property_id_type()( my->_db ).current_hardfork_version; + return my->_db.get(hardfork_property_id_type()).current_hardfork_version; }); } @@ -326,7 +326,7 @@ scheduled_hardfork database_api::get_next_scheduled_hardfork() const return my->_db.with_read_lock( [&]() { scheduled_hardfork shf; - const auto& hpo = hardfork_property_id_type()( my->_db ); + const auto& hpo = my->_db.get(hardfork_property_id_type()); shf.hf_version = hpo.next_hardfork; shf.live_time = hpo.next_hardfork_time; return shf; @@ -391,7 +391,7 @@ vector< extended_account > database_api_impl::get_accounts( vector< string > nam auto vitr = vidx.lower_bound( boost::make_tuple( itr->id, witness_id_type() ) ); while( vitr != vidx.end() && vitr->account == itr->id ) { - results.back().witness_votes.insert(vitr->witness(_db).owner); + results.back().witness_votes.insert(_db.get(vitr->witness).owner); ++vitr; } } @@ -560,7 +560,7 @@ vector< withdraw_route > database_api::get_withdraw_routes( string account, with { withdraw_route r; r.from_account = account; - r.to_account = route->to_account( my->_db ).name; + r.to_account = my->_db.get( route->to_account ).name; r.percent = route->percent; r.auto_vest = route->auto_vest; @@ -578,7 +578,7 @@ vector< withdraw_route > database_api::get_withdraw_routes( string account, with while( route != by_dest.end() && route->to_account == acc.id ) { withdraw_route r; - r.from_account = route->from_account( my->_db ).name; + r.from_account = my->_db.get( route->from_account ).name; r.to_account = account; r.percent = route->percent; r.auto_vest = route->auto_vest; @@ -823,7 +823,7 @@ vector< liquidity_balance > database_api_impl::get_liquidity_queue( string start while( itr != liq_idx.end() && result.size() < limit ) { liquidity_balance bal; - bal.account = itr->owner( _db ).name; + bal.account = _db.get(itr->owner).name; bal.weight = itr->weight; result.push_back( bal ); @@ -1000,7 +1000,7 @@ vector database_api::get_active_votes( string author, string permlin auto itr = idx.lower_bound( cid ); while( itr != idx.end() && itr->comment == cid ) { - const auto& vo = itr->voter(my->_db); + const auto& vo = my->_db.get(itr->voter); vote_state vstate; vstate.voter = vo.name; vstate.weight = itr->weight; @@ -1036,7 +1036,7 @@ vector database_api::get_account_votes( string voter )const auto end = idx.upper_bound( aid ); while( itr != end ) { - const auto& vo = itr->comment(my->_db); + const auto& vo = my->_db.get(itr->comment); account_vote avote; avote.authorperm = vo.author+"/"+to_string( vo.permlink ); avote.weight = itr->weight; @@ -1196,7 +1196,7 @@ map< uint32_t, applied_operation > database_api::get_account_history( string acc map result; while( itr != end ) { - result[itr->sequence] = itr->op(my->_db); + result[itr->sequence] = my->_db.get(itr->op); ++itr; } return result; @@ -1235,7 +1235,7 @@ vector database_api::get_trending_tags( string after, uint32_t limi discussion database_api::get_discussion( comment_id_type id )const { - discussion d = id(my->_db); + discussion d = my->_db.get(id); set_url( d ); set_pending_payout( d ); d.active_votes = get_active_votes( d.author, d.permlink ); diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index ff50078c2e..84c8ae7d3e 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -1598,7 +1598,7 @@ void database::adjust_witness_votes( const account_object& a, share_type delta ) auto itr = vidx.lower_bound( boost::make_tuple( a.id, witness_id_type() ) ); while( itr != vidx.end() && itr->account == a.id ) { - adjust_witness_vote( itr->witness(*this), delta ); + adjust_witness_vote( get(itr->witness), delta ); ++itr; } } @@ -1791,7 +1791,7 @@ void database::process_vesting_withdrawals() if( to_deposit > 0 ) { - const auto& to_account = itr->to_account( *this ); + const auto& to_account = get(itr->to_account); modify( to_account, [&]( account_object& a ) { @@ -1811,7 +1811,7 @@ void database::process_vesting_withdrawals() { if( !itr->auto_vest ) { - const auto& to_account = itr->to_account( *this ); + const auto& to_account = get(itr->to_account); share_type to_deposit = ( ( fc::uint128_t ( to_withdraw.value ) * itr->percent ) / STEEMIT_100_PERCENT ).to_uint64(); vests_deposited_as_steem += to_deposit; @@ -1904,7 +1904,7 @@ share_type database::pay_discussions( const comment_object& c, share_type max_re // Pre-order traversal of the tree of child comments while( child_queue.size() ) { - const auto& cur = child_queue.front()( *this ); + const auto& cur = get(child_queue.front()); child_queue.pop_front(); if( cur.net_rshares > 0 ) @@ -1957,7 +1957,7 @@ share_type database::pay_curators( const comment_object& c, share_type max_rewar if( claim > 0 ) // min_amt is non-zero satoshis { unclaimed_rewards -= claim; - const auto& voter = itr->voter(*this); + const auto& voter = get(itr->voter); auto reward = create_vesting( voter, asset( claim, STEEM_SYMBOL ) ); push_virtual_operation( curation_reward_operation( voter.name, reward, c.author, to_string( c.permlink ) ) ); @@ -2334,7 +2334,7 @@ void database::pay_liquidity_reward() if( itr != ridx.end() && itr->volume_weight() > 0 ) { adjust_supply( reward, true ); - adjust_balance( itr->owner(*this), reward ); + adjust_balance( get(itr->owner), reward ); modify( *itr, [&]( liquidity_reward_balance_object& obj ) { obj.steem_volume = 0; @@ -2343,7 +2343,7 @@ void database::pay_liquidity_reward() obj.weight = 0; } ); - push_virtual_operation( liquidity_reward_operation( itr->owner( *this ).name, reward ) ); + push_virtual_operation( liquidity_reward_operation( get(itr->owner).name, reward ) ); } } } @@ -2538,7 +2538,7 @@ void database::process_decline_voting_rights() while( itr != request_idx.end() && itr->effective_date <= head_block_time() ) { - const auto& account = itr->account(*this); + const auto& account = get(itr->account); /// remove all current votes std::array delta; @@ -2549,7 +2549,7 @@ void database::process_decline_voting_rights() clear_witness_votes( account ); - modify( itr->account(*this), [&]( account_object& a ) + modify( get(itr->account), [&]( account_object& a ) { a.can_vote = false; a.proxy = STEEMIT_PROXY_TO_SELF_ACCOUNT; @@ -3311,7 +3311,7 @@ const witness_object& database::validate_block_header( uint32_t skip, const sign { FC_ASSERT( head_block_id() == next_block.previous, "", ("head_block_id",head_block_id())("next.prev",next_block.previous) ); FC_ASSERT( head_block_time() < next_block.timestamp, "", ("head_block_time",head_block_time())("next",next_block.timestamp)("blocknum",next_block.block_num()) ); - const witness_object& witness = get_witness( next_block.witness ); //(*this); + const witness_object& witness = get_witness( next_block.witness ); if( !(skip&skip_witness_signature) ) FC_ASSERT( next_block.validate_signee( witness.signing_key ) ); @@ -4479,7 +4479,7 @@ void database::retally_witness_votes() auto wit_itr = vidx.lower_bound( boost::make_tuple( a.id, witness_id_type() ) ); while( wit_itr != vidx.end() && wit_itr->account == a.id ) { - adjust_witness_vote( wit_itr->witness(*this), a.witness_vote_weight() ); + adjust_witness_vote( get(wit_itr->witness), a.witness_vote_weight() ); ++wit_itr; } } diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 37088f234d..ccf6e9450d 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -369,7 +369,7 @@ void comment_evaluator::do_apply( const comment_operation& o ) { if( o.parent_author != STEEMIT_ROOT_POST_PARENT ) { - FC_ASSERT( parent->root_comment( _db ).allow_replies, "The parent comment has disabled replies." ); + FC_ASSERT( _db.get( parent->root_comment ).allow_replies, "The parent comment has disabled replies." ); if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__177) ) FC_ASSERT( _db.calculate_discussion_payout_time( *parent ) != fc::time_point_sec::maximum(), "Discussion is frozen." ); } @@ -1116,7 +1116,7 @@ void vote_evaluator::do_apply( const vote_operation& o ) /// if the current net_rshares is less than 0, the post is getting 0 rewards so it is not factored into total rshares^2 fc::uint128_t old_rshares = std::max(comment.net_rshares.value, int64_t(0)); - const auto& root = comment.root_comment( _db ); + const auto& root = _db.get( comment.root_comment ); auto old_root_abs_rshares = root.children_abs_rshares.value; fc::uint128_t cur_cashout_time_sec = _db.calculate_discussion_payout_time( comment ).sec_since_epoch(); @@ -1276,7 +1276,7 @@ void vote_evaluator::do_apply( const vote_operation& o ) /// if the current net_rshares is less than 0, the post is getting 0 rewards so it is not factored into total rshares^2 fc::uint128_t old_rshares = std::max(comment.net_rshares.value, int64_t(0)); - const auto& root = comment.root_comment( _db ); + const auto& root = _db.get( comment.root_comment ); auto old_root_abs_rshares = root.children_abs_rshares.value; fc::uint128_t cur_cashout_time_sec = _db.calculate_discussion_payout_time( comment ).sec_since_epoch(); diff --git a/libraries/chainbase b/libraries/chainbase index a1ca930951..3f86a4c648 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit a1ca93095197bbe9e2eb6716c28ee351cd95b174 +Subproject commit 3f86a4c6483c8a07aec4b568bcd0a3708aca1c5f diff --git a/libraries/plugins/blockchain_statistics/blockchain_statistics_api.cpp b/libraries/plugins/blockchain_statistics/blockchain_statistics_api.cpp index 3ed53ca995..f0a82670f6 100644 --- a/libraries/plugins/blockchain_statistics/blockchain_statistics_api.cpp +++ b/libraries/plugins/blockchain_statistics/blockchain_statistics_api.cpp @@ -60,7 +60,7 @@ namespace detail statistics blockchain_statistics_api_impl::get_lifetime_stats()const { statistics result; - result += bucket_id_type()( *( _app.chain_database() ) ); + result += _app.chain_database()->get( bucket_id_type() ); return result; } diff --git a/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp b/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp index ca6076eb0a..39aa11a975 100644 --- a/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp +++ b/libraries/plugins/blockchain_statistics/blockchain_statistics_plugin.cpp @@ -259,7 +259,7 @@ void blockchain_statistics_plugin_impl::on_block( const signed_block& b ) } else { - db.modify( bucket_id_type()( db ), [&]( bucket_object& bo ) + db.modify( db.get( bucket_id_type() ), [&]( bucket_object& bo ) { bo.blocks++; }); @@ -341,7 +341,7 @@ void blockchain_statistics_plugin_impl::pre_operation( const operation_notificat { delete_comment_operation op = o.op.get< delete_comment_operation >(); auto comment = db.get_comment( op.author, op.permlink ); - const auto& bucket = bucket_id( db ); + const auto& bucket = db.get(bucket_id); db.modify( bucket, [&]( bucket_object& b ) { @@ -355,7 +355,7 @@ void blockchain_statistics_plugin_impl::pre_operation( const operation_notificat { withdraw_vesting_operation op = o.op.get< withdraw_vesting_operation >(); auto& account = db.get_account( op.account ); - const auto& bucket = bucket_id( db ); + const auto& bucket = db.get(bucket_id); auto new_vesting_withdrawal_rate = op.vesting_shares.amount / STEEMIT_VESTING_WITHDRAW_INTERVALS; if( op.vesting_shares.amount > 0 && new_vesting_withdrawal_rate == 0 ) @@ -386,7 +386,7 @@ void blockchain_statistics_plugin_impl::post_operation( const operation_notifica for( auto bucket_id : _current_buckets ) { - const auto& bucket = bucket_id( db ); + const auto& bucket = db.get(bucket_id); if( !is_virtual_operation( o.op ) ) { diff --git a/libraries/plugins/debug_node/debug_node_api.cpp b/libraries/plugins/debug_node/debug_node_api.cpp index 736d0e579f..67f4b83575 100644 --- a/libraries/plugins/debug_node/debug_node_api.cpp +++ b/libraries/plugins/debug_node/debug_node_api.cpp @@ -235,12 +235,12 @@ fc::optional< steemit::chain::signed_block > debug_node_api_impl::debug_pop_bloc steemit::chain::witness_schedule_object debug_node_api_impl::debug_get_witness_schedule() { - return steemit::chain::witness_schedule_id_type()( *app.chain_database() ); + return app.chain_database()->get( steemit::chain::witness_schedule_id_type() ); } steemit::chain::hardfork_property_object debug_node_api_impl::debug_get_hardfork_property_object() { - return steemit::chain::hardfork_property_id_type()( *app.chain_database() ); + return app.chain_database()->get( steemit::chain::hardfork_property_id_type() ); } void debug_node_api_impl::debug_update_object( const fc::variant_object& update ) @@ -290,8 +290,7 @@ void debug_node_api_impl::debug_set_hardfork( uint32_t hardfork_id ) bool debug_node_api_impl::debug_has_hardfork( uint32_t hardfork_id ) { - idump( (steemit::chain::hardfork_property_id_type()( *app.chain_database() ))(hardfork_id) ); - return steemit::chain::hardfork_property_id_type()( *app.chain_database() ).last_hardfork >= hardfork_id; + return app.chain_database()->get( steemit::chain::hardfork_property_id_type() ).last_hardfork >= hardfork_id; } void debug_node_api_impl::debug_get_json_schema( std::string& schema ) diff --git a/libraries/plugins/follow/follow_api.cpp b/libraries/plugins/follow/follow_api.cpp index 0f11f4e69d..e3e24f762a 100644 --- a/libraries/plugins/follow/follow_api.cpp +++ b/libraries/plugins/follow/follow_api.cpp @@ -114,7 +114,7 @@ vector< feed_entry > follow_api_impl::get_feed_entries( string account, uint32_t while( itr != feed_idx.end() && itr->account == account && results.size() < limit ) { - const auto& comment = itr->comment( db ); + const auto& comment = db.get( itr->comment ); feed_entry entry; entry.author = comment.author; entry.permlink = to_string( comment.permlink ); @@ -148,7 +148,7 @@ vector< comment_feed_entry > follow_api_impl::get_feed( string account, uint32_t while( itr != feed_idx.end() && itr->account == account && results.size() < limit ) { - const auto& comment = itr->comment( db ); + const auto& comment = db.get( itr->comment ); comment_feed_entry entry; entry.comment = comment; entry.entry_id = itr->account_feed_id; @@ -181,7 +181,7 @@ vector< blog_entry > follow_api_impl::get_blog_entries( string account, uint32_t while( itr != blog_idx.end() && itr->account == account && results.size() < limit ) { - const auto& comment = itr->comment( db ); + const auto& comment = db.get( itr->comment ); blog_entry entry; entry.author = comment.author; entry.permlink = to_string( comment.permlink ); @@ -213,7 +213,7 @@ vector< comment_blog_entry > follow_api_impl::get_blog( string account, uint32_t while( itr != blog_idx.end() && itr->account == account && results.size() < limit ) { - const auto& comment = itr->comment( db ); + const auto& comment = db.get( itr->comment ); comment_blog_entry entry; entry.comment = comment; entry.blog = account; diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index d8d25c5d31..2a0b6da5dc 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -470,7 +470,7 @@ void database_fixture::set_price_feed( const price& new_price ) #ifdef IS_TEST_NET !db.skip_price_feed_limit_check || #endif - feed_history_id_type()( db ).current_median_history == new_price + db.get(feed_history_id_type()).current_median_history == new_price ); } @@ -493,7 +493,7 @@ vector< operation > database_fixture::get_last_operations( uint32_t num_ops ) while( itr != acc_hist_idx.begin() && ops.size() < num_ops ) { itr--; - ops.push_back( fc::raw::unpack< steemit::chain::operation >( itr->op(db).serialized_op ) ); + ops.push_back( fc::raw::unpack< steemit::chain::operation >( db.get(itr->op).serialized_op ) ); } return ops; diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 5a254dac88..3dd861fe3e 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -247,24 +247,24 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create ) auto b = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); auto alice_id = db1.get_account( "alice" ).id; - BOOST_CHECK( alice_id(db1).name == "alice" ); + BOOST_CHECK( db1.get(alice_id).name == "alice" ); b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); - STEEMIT_REQUIRE_THROW(alice_id(db2), std::exception); - alice_id(db1); /// it should be included in the pending state + STEEMIT_REQUIRE_THROW(db2.get(alice_id), std::exception); + db1.get(alice_id); /// it should be included in the pending state db1.clear_pending(); // clear it so that we can verify it was properly removed from pending state. - STEEMIT_REQUIRE_THROW(alice_id(db1), std::exception); + STEEMIT_REQUIRE_THROW(db1.get(alice_id), std::exception); PUSH_TX( db2, trx ); b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); - BOOST_CHECK(alice_id(db1).name == "alice"); - BOOST_CHECK(alice_id(db2).name == "alice"); + BOOST_CHECK( db1.get(alice_id).name == "alice"); + BOOST_CHECK( db2.get(alice_id).name == "alice"); } catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -756,7 +756,7 @@ BOOST_FIXTURE_TEST_CASE( hardfork_test, database_fixture ) BOOST_REQUIRE( db.has_hardfork( 0 ) ); BOOST_REQUIRE( db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ); BOOST_REQUIRE( get_last_operations( 1 )[0].get< custom_operation >().data == vector< char >( op_msg.begin(), op_msg.end() ) ); - BOOST_REQUIRE( itr->op(db).timestamp == db.head_block_time() ); + BOOST_REQUIRE( db.get(itr->op).timestamp == db.head_block_time() ); BOOST_TEST_MESSAGE( "Testing hardfork is only applied once" ); generate_block(); @@ -767,7 +767,7 @@ BOOST_FIXTURE_TEST_CASE( hardfork_test, database_fixture ) BOOST_REQUIRE( db.has_hardfork( 0 ) ); BOOST_REQUIRE( db.has_hardfork( STEEMIT_HARDFORK_0_1 ) ); BOOST_REQUIRE( get_last_operations( 1 )[0].get< custom_operation >().data == vector< char >( op_msg.begin(), op_msg.end() ) ); - BOOST_REQUIRE( itr->op(db).timestamp == db.head_block_time() - STEEMIT_BLOCK_INTERVAL ); + BOOST_REQUIRE( db.get(itr->op).timestamp == db.head_block_time() - STEEMIT_BLOCK_INTERVAL ); } FC_LOG_AND_RETHROW() } diff --git a/tests/tests/live_tests.cpp b/tests/tests/live_tests.cpp index 70ccd02370..64d98d7a21 100644 --- a/tests/tests/live_tests.cpp +++ b/tests/tests/live_tests.cpp @@ -160,9 +160,9 @@ BOOST_AUTO_TEST_CASE( retally_votes ) for( auto vote: by_account_witness_idx ) { if( expected_votes.find( vote.witness ) == expected_votes.end() ) - expected_votes[ vote.witness ] = vote.account( db ).witness_vote_weight(); + expected_votes[ vote.witness ] = db.get( vote.account ).witness_vote_weight(); else - expected_votes[ vote.witness ] += vote.account( db ).witness_vote_weight(); + expected_votes[ vote.witness ] += db.get( vote.account ).witness_vote_weight(); } db.retally_witness_votes(); diff --git a/tests/tests/operation_time_tests.cpp b/tests/tests/operation_time_tests.cpp index b28a9eb24d..febf196cc3 100644 --- a/tests/tests/operation_time_tests.cpp +++ b/tests/tests/operation_time_tests.cpp @@ -1157,7 +1157,7 @@ BOOST_AUTO_TEST_CASE( feed_publish_mean ) BOOST_TEST_MESSAGE( "Check feed_history" ); - feed_history = feed_history_id_type()( db ); + feed_history = db.get(feed_history_id_type()); BOOST_REQUIRE( feed_history.current_median_history == feed_history.price_history[ ( i + 1 ) / 2 ] ); BOOST_REQUIRE( feed_history.price_history[ i + 1 ] == ops[4].exchange_rate ); validate_database(); From fbbc80e62010e7c05b284f7ae0a6879d416c73c6 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 9 Dec 2016 13:15:25 -0500 Subject: [PATCH 24/77] Explicitly name sentinel value #606 --- libraries/chain/block_log.cpp | 4 ++-- .../chain/include/steemit/chain/block_log.hpp | 6 ++++++ .../plugins/debug_node/debug_node_api.cpp | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index 9814a0baa7..7a2110101c 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -204,7 +204,7 @@ namespace steemit { namespace chain { { optional< signed_block > b; uint64_t pos = get_block_pos( block_num ); - if( ~pos ) + if( pos != npos ) b = read_block( pos ).first; return b; } @@ -214,7 +214,7 @@ namespace steemit { namespace chain { my->check_index_read(); if( !( my->head && block_num <= protocol::block_header::num_from_id( my->head_id ) ) ) - return ~0; + return npos; my->index_stream.seekg( sizeof( uint64_t ) * ( block_num - 1 ) ); uint64_t pos; my->index_stream.read( (char*)&pos, sizeof( pos ) ); diff --git a/libraries/chain/include/steemit/chain/block_log.hpp b/libraries/chain/include/steemit/chain/block_log.hpp index 156fd636d8..a8ebb7e2c6 100644 --- a/libraries/chain/include/steemit/chain/block_log.hpp +++ b/libraries/chain/include/steemit/chain/block_log.hpp @@ -46,10 +46,16 @@ namespace steemit { namespace chain { void flush(); std::pair< signed_block, uint64_t > read_block( uint64_t file_pos )const; optional< signed_block > read_block_by_num( uint32_t block_num )const; + + /** + * Return offset of block in file, or block_log::npos if it does not exist. + */ uint64_t get_block_pos( uint32_t block_num ) const; signed_block read_head()const; const optional< signed_block >& head()const; + static const uint64_t npos = std::numeric_limits::max(); + private: void construct_index( uint64_t start_pos ); diff --git a/libraries/plugins/debug_node/debug_node_api.cpp b/libraries/plugins/debug_node/debug_node_api.cpp index 736d0e579f..5c2e87f1d5 100644 --- a/libraries/plugins/debug_node/debug_node_api.cpp +++ b/libraries/plugins/debug_node/debug_node_api.cpp @@ -189,13 +189,25 @@ uint32_t debug_node_api_impl::debug_push_blocks( const std::string& src_filename for( uint32_t i=0; i block = log.read_block( log.get_block_pos( first_block + i ) ); - auto result = log.read_block( log.get_block_pos( first_block + i ) ); - - if( result.second == ~0 ) + uint64_t block_pos = log.get_block_pos( first_block + i ); + if( block_pos == steemit::chain::block_log::npos ) { wlog( "Block database ${fn} only contained ${i} of ${n} requested blocks", ("i", i)("n", count)("fn", src_filename) ); return i; } + + decltype( log.read_block(0) ) result; + + try + { + result = log.read_block( block_pos ); + } + catch( const fc::exception& e ) + { + elog( "Could not read block ${i} of ${n}", ("i", i)("n", count) ); + continue; + } + try { db->push_block( result.first, skip_flags ); From f409f751cae38192ad3987209ab05c76239f4a80 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 12 Dec 2016 17:52:48 -0500 Subject: [PATCH 25/77] Removed packed_block #675 --- libraries/chain/database.cpp | 27 +++---------------- .../steemit/chain/block_summary_object.hpp | 4 +-- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index eff05b71e2..b454a157a5 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -248,7 +248,7 @@ optional database::fetch_block_by_id( const block_id_type& id )con auto b = _fork_db.fetch_block( id ); if( !b ) { - auto tmp = fetch_block_by_number( protocol::block_header::num_from_id( id ) ); + auto tmp = _block_log.read_block_by_num( protocol::block_header::num_from_id( id ) ); if( tmp && tmp->id() == id ) return tmp; @@ -264,21 +264,11 @@ optional database::fetch_block_by_number( uint32_t block_num )cons { optional< signed_block > b; - const auto* stats = find< block_stats_object >( block_num - 1 ); - - if( !stats ) - return b; - - if( stats->packed_block.size() ) - { - signed_block block; - fc::raw::unpack( stats->packed_block, block ); - b = block; - } + auto results = _fork_db.fetch_block_by_number( block_num ); + if( results.size() == 1 ) + b = results[0]->data; else - { b = _block_log.read_block_by_num( block_num ); - } return b; } @@ -3050,8 +3040,6 @@ void database::_apply_block( const signed_block& next_block ) { assert( bso.block_num() == next_block_num ); // Probably can be taken out. Sanity check bso.block_id = next_block_id; - if( !( get_node_properties().skip_flags & skip_block_log ) ) - fc::raw::pack( bso.packed_block, next_block ); }); update_global_dynamic_data(next_block); @@ -3542,13 +3530,6 @@ void database::update_last_irreversible_block() while( log_head_num < dpo.last_irreversible_block_num ) { _block_log.append( *fetch_block_by_number( log_head_num + 1 ) ); - - // Block stats object IDs are block num - 1, so the ID is ( log_head_num + 1 ) - 1 - modify( get< block_stats_object >( log_head_num ), [&]( block_stats_object& bso ) - { - bso.packed_block.clear(); - }); - log_head_num++; } diff --git a/libraries/chain/include/steemit/chain/block_summary_object.hpp b/libraries/chain/include/steemit/chain/block_summary_object.hpp index b765d357d3..b0999a3ebb 100644 --- a/libraries/chain/include/steemit/chain/block_summary_object.hpp +++ b/libraries/chain/include/steemit/chain/block_summary_object.hpp @@ -43,14 +43,12 @@ namespace steemit { namespace chain { public: template< typename Constructor, typename Allocator > block_stats_object( Constructor&& c, allocator< Allocator > a ) - :packed_block( a ) { c( *this ); } id_type id; block_id_type block_id; - bip::vector< char, allocator< char > > packed_block; uint64_t block_num()const { return id._id + 1; } }; @@ -73,5 +71,5 @@ namespace steemit { namespace chain { FC_REFLECT( steemit::chain::block_summary_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_summary_object, steemit::chain::block_summary_index ) -FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id)(packed_block) ) +FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_stats_object, steemit::chain::block_stats_index ) From fef44c9d5492c6f9a74a3c79faafe9444a0a3396 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 13 Dec 2016 11:00:41 -0500 Subject: [PATCH 26/77] Progress bug fixing --- libraries/chain/block_log.cpp | 4 +++ libraries/chain/database.cpp | 35 +++++++++++++++++-- libraries/chain/fork_database.cpp | 4 +++ .../steemit/chain/block_summary_object.hpp | 4 ++- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index 7daaa11700..b3d95607cb 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -199,11 +199,15 @@ namespace steemit { namespace chain { optional< signed_block > block_log::read_block_by_num( uint32_t block_num )const { + try + { optional< signed_block > b; uint64_t pos = get_block_pos( block_num ); if( ~pos ) b = read_block( pos ).first; return b; + } + FC_LOG_AND_RETHROW() } uint64_t block_log::get_block_pos( uint32_t block_num ) const diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index b454a157a5..3b2ec29c9e 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -128,7 +128,13 @@ void database::open( const fc::path& data_dir, const fc::path& shared_mem_dir, u }); if( head_block_num() ) - _fork_db.start_block( *fetch_block_by_number( head_block_num() ) ); + { + auto head_block = _block_log.read_block_by_num( head_block_num() ); + // This assertion should be caught and a reindex should occur + FC_ASSERT( head_block.valid() && head_block->id() == head_block_id(), "Chain state does not match block log. Please reindex blockchain." ); + + _fork_db.start_block( *head_block ); + } } init_hardforks(); @@ -248,7 +254,7 @@ optional database::fetch_block_by_id( const block_id_type& id )con auto b = _fork_db.fetch_block( id ); if( !b ) { - auto tmp = _block_log.read_block_by_num( protocol::block_header::num_from_id( id ) ); + auto tmp = fetch_block_by_number( protocol::block_header::num_from_id( id ) ); if( tmp && tmp->id() == id ) return tmp; @@ -264,11 +270,36 @@ optional database::fetch_block_by_number( uint32_t block_num )cons { optional< signed_block > b; + /* + const auto* stats = find< block_stats_object >( block_num - 1 ); + + if( !stats ) + return b; + + if( stats->packed_block.size() ) + { + signed_block block; + fc::raw::unpack( stats->packed_block, block ); + b = block; + } + else + { + b = _block_log.read_block_by_num( block_num ); + } + //*/ + + //* + try{ auto results = _fork_db.fetch_block_by_number( block_num ); if( results.size() == 1 ) b = results[0]->data; else b = _block_log.read_block_by_num( block_num ); + } + FC_LOG_AND_RETHROW() + //*/ + + //idump( (block_num)(b) ); return b; } diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index d2910da00a..9276b64ba0 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -160,6 +160,8 @@ item_ptr fork_database::fetch_block(const block_id_type& id)const vector fork_database::fetch_block_by_number(uint32_t num)const { + try + { vector result; auto itr = _index.get().find(num); while( itr != _index.get().end() ) @@ -171,6 +173,8 @@ vector fork_database::fetch_block_by_number(uint32_t num)const ++itr; } return result; + } + FC_LOG_AND_RETHROW() } pair diff --git a/libraries/chain/include/steemit/chain/block_summary_object.hpp b/libraries/chain/include/steemit/chain/block_summary_object.hpp index b0999a3ebb..b765d357d3 100644 --- a/libraries/chain/include/steemit/chain/block_summary_object.hpp +++ b/libraries/chain/include/steemit/chain/block_summary_object.hpp @@ -43,12 +43,14 @@ namespace steemit { namespace chain { public: template< typename Constructor, typename Allocator > block_stats_object( Constructor&& c, allocator< Allocator > a ) + :packed_block( a ) { c( *this ); } id_type id; block_id_type block_id; + bip::vector< char, allocator< char > > packed_block; uint64_t block_num()const { return id._id + 1; } }; @@ -71,5 +73,5 @@ namespace steemit { namespace chain { FC_REFLECT( steemit::chain::block_summary_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_summary_object, steemit::chain::block_summary_index ) -FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id) ) +FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id)(packed_block) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_stats_object, steemit::chain::block_stats_index ) From adae614e9d762f72436effab8df8e7ab485c86df Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 13 Dec 2016 11:45:07 -0500 Subject: [PATCH 27/77] Remove packed_block #675 --- libraries/chain/block_log.cpp | 6 +++- libraries/chain/database.cpp | 29 ++----------------- .../steemit/chain/block_summary_object.hpp | 5 +--- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index d9478fdc0a..507ffd7881 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -41,12 +41,16 @@ namespace steemit { namespace chain { inline void check_index_read() { + try + { if( index_write ) { index_stream.close(); index_stream.open( index_file.generic_string().c_str(), LOG_READ ); index_write = false; } + } + FC_LOG_AND_RETHROW() } inline void check_index_write() @@ -214,7 +218,7 @@ namespace steemit { namespace chain { { my->check_index_read(); - if( !( my->head && block_num <= protocol::block_header::num_from_id( my->head_id ) ) ) + if( !( my->head.valid() && block_num <= protocol::block_header::num_from_id( my->head_id ) && block_num > 0 ) ) return npos; my->index_stream.seekg( sizeof( uint64_t ) * ( block_num - 1 ) ); uint64_t pos; diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 6468a04e20..cbb7c0d416 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -245,7 +245,7 @@ bool database::is_known_transaction( const transaction_id_type& id )const return trx_idx.find( id ) != trx_idx.end(); } -block_id_type database::get_block_id_for_num( uint32_t block_num )const +block_id_type database::get_block_id_for_num( uint32_t block_num )const { return get< block_stats_object >( block_num - 1 ).block_id; } @@ -255,7 +255,7 @@ optional database::fetch_block_by_id( const block_id_type& id )con auto b = _fork_db.fetch_block( id ); if( !b ) { - auto tmp = fetch_block_by_number( protocol::block_header::num_from_id( id ) ); + auto tmp = _block_log.read_block_by_num( protocol::block_header::num_from_id( id ) ); if( tmp && tmp->id() == id ) return tmp; @@ -271,36 +271,11 @@ optional database::fetch_block_by_number( uint32_t block_num )cons { optional< signed_block > b; - /* - const auto* stats = find< block_stats_object >( block_num - 1 ); - - if( !stats ) - return b; - - if( stats->packed_block.size() ) - { - signed_block block; - fc::raw::unpack( stats->packed_block, block ); - b = block; - } - else - { - b = _block_log.read_block_by_num( block_num ); - } - //*/ - - //* - try{ auto results = _fork_db.fetch_block_by_number( block_num ); if( results.size() == 1 ) b = results[0]->data; else b = _block_log.read_block_by_num( block_num ); - } - FC_LOG_AND_RETHROW() - //*/ - - //idump( (block_num)(b) ); return b; } diff --git a/libraries/chain/include/steemit/chain/block_summary_object.hpp b/libraries/chain/include/steemit/chain/block_summary_object.hpp index b765d357d3..d608eecb08 100644 --- a/libraries/chain/include/steemit/chain/block_summary_object.hpp +++ b/libraries/chain/include/steemit/chain/block_summary_object.hpp @@ -43,15 +43,12 @@ namespace steemit { namespace chain { public: template< typename Constructor, typename Allocator > block_stats_object( Constructor&& c, allocator< Allocator > a ) - :packed_block( a ) { c( *this ); } id_type id; block_id_type block_id; - bip::vector< char, allocator< char > > packed_block; - uint64_t block_num()const { return id._id + 1; } }; @@ -73,5 +70,5 @@ namespace steemit { namespace chain { FC_REFLECT( steemit::chain::block_summary_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_summary_object, steemit::chain::block_summary_index ) -FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id)(packed_block) ) +FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_stats_object, steemit::chain::block_stats_index ) From d4ba29d3ca830bfcce90183d2f1c871b9bd9183b Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 13 Dec 2016 13:15:00 -0500 Subject: [PATCH 28/77] Remove block_stats_object #675 --- libraries/chain/database.cpp | 28 ++++++++--------- .../steemit/chain/block_summary_object.hpp | 30 ------------------- libraries/chain/steem_evaluator.cpp | 2 +- 3 files changed, 14 insertions(+), 46 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index cbb7c0d416..2bad13fb21 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -114,12 +114,6 @@ void database::open( const fc::path& data_dir, const fc::path& shared_mem_dir, u auto log_head = _block_log.head(); - // block_log.head must be in block stats - // If it is not, print warning and exit - if( log_head && head_block_num() ) - FC_ASSERT( get< block_stats_object >( log_head->block_num() - 1 ).block_id == log_head->id(), - "Head block of log file is not included in current chain state. log_head: ${log_head}", ("log_head", log_head) ); - // Rewind all undo state. This should return us to the state at the last irreversible block. with_write_lock( [&]() { @@ -231,7 +225,7 @@ void database::close(bool rewind) bool database::is_known_block( const block_id_type& id )const { - return _fork_db.is_known_block(id) || find< block_stats_object, by_block_id >( id ); + return fetch_block_by_id( id ).valid(); } /** @@ -247,7 +241,18 @@ bool database::is_known_transaction( const transaction_id_type& id )const block_id_type database::get_block_id_for_num( uint32_t block_num )const { - return get< block_stats_object >( block_num - 1 ).block_id; + try + { + auto b = _block_log.read_block_by_num( block_num ); + if( b.valid() ) + return b->id(); + + auto results = _fork_db.fetch_block_by_number( block_num ); + FC_ASSERT( results.size() == 1 ); + return results[0]->data.id(); + + } + FC_CAPTURE_AND_RETHROW( (block_num) ) } optional database::fetch_block_by_id( const block_id_type& id )const @@ -2675,7 +2680,6 @@ void database::initialize_indexes() add_core_index< escrow_index >(*this); add_core_index< savings_withdraw_index >(*this); add_core_index< decline_voting_rights_request_index >(*this); - add_core_index< block_stats_index >(*this); _plugin_index_signal(); } @@ -3043,12 +3047,6 @@ void database::_apply_block( const signed_block& next_block ) ++_current_trx_in_block; } - create< block_stats_object >( [&]( block_stats_object& bso ) - { - assert( bso.block_num() == next_block_num ); // Probably can be taken out. Sanity check - bso.block_id = next_block_id; - }); - update_global_dynamic_data(next_block); update_signing_witness(signing_witness, next_block); diff --git a/libraries/chain/include/steemit/chain/block_summary_object.hpp b/libraries/chain/include/steemit/chain/block_summary_object.hpp index d608eecb08..6ddd98e95c 100644 --- a/libraries/chain/include/steemit/chain/block_summary_object.hpp +++ b/libraries/chain/include/steemit/chain/block_summary_object.hpp @@ -38,37 +38,7 @@ namespace steemit { namespace chain { allocator< block_summary_object > > block_summary_index; - class block_stats_object : public object< block_stats_object_type, block_stats_object > - { - public: - template< typename Constructor, typename Allocator > - block_stats_object( Constructor&& c, allocator< Allocator > a ) - { - c( *this ); - } - - id_type id; - block_id_type block_id; - uint64_t block_num()const { return id._id + 1; } - }; - - struct by_block_id; - - typedef multi_index_container< - block_stats_object, - indexed_by< - ordered_unique< tag< by_id >, - member< block_stats_object, block_stats_id_type, &block_stats_object::id > >, - ordered_unique< tag< by_block_id >, - member< block_stats_object, block_id_type, &block_stats_object::block_id > > - >, - allocator< block_stats_object > - > block_stats_index; - } } // steemit::chain FC_REFLECT( steemit::chain::block_summary_object, (id)(block_id) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_summary_object, steemit::chain::block_summary_index ) - -FC_REFLECT( steemit::chain::block_stats_object, (id)(block_id) ) -CHAINBASE_SET_INDEX_TYPE( steemit::chain::block_stats_object, steemit::chain::block_stats_index ) diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 7bcfcdfd86..3fec0bc4a5 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -1490,7 +1490,7 @@ void pow2_evaluator::do_apply( const pow2_operation& o ) { const auto& work = o.work.get< equihash_pow >(); FC_ASSERT( work.prev_block == db.head_block_id(), "Equihash pow op not for last block" ); - auto recent_block_num = db.get< block_stats_object, by_block_id >( work.input.prev_block ).block_num(); + auto recent_block_num = protocol::block_header::num_from_id( work.input.prev_block ); FC_ASSERT( recent_block_num > dgp.last_irreversible_block_num, "Equihash pow done for block older than last irreversible block num" ); FC_ASSERT( work.pow_summary < target_pow, "Insufficient work difficulty. Work: ${w}, Target: ${t}", ("w",work.pow_summary)("t", target_pow) ); From 3fe01234efd2b924a2f834ab2df9a537a719e1b1 Mon Sep 17 00:00:00 2001 From: JustinW Date: Wed, 14 Dec 2016 17:18:21 -0500 Subject: [PATCH 29/77] Added tagging for latest image on dockerhub if the branchname is named stable, added build context for github status (so that it does't report as 'default'), and now removing exited docker containers. --- ciscripts/buildfailure.sh | 5 ++++- ciscripts/buildpending.sh | 3 ++- ciscripts/buildscript.sh | 3 +++ ciscripts/buildsuccess.sh | 5 ++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ciscripts/buildfailure.sh b/ciscripts/buildfailure.sh index 08adb9f069..9b0e3db696 100755 --- a/ciscripts/buildfailure.sh +++ b/ciscripts/buildfailure.sh @@ -2,6 +2,9 @@ curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ \"state\": \"failure\", \"target_url\": \"${BUILD_URL}\", - \"description\": \"JenkinsCI reports the build has failed!\" + \"description\": \"JenkinsCI reports the build has failed!\", + \"context\": \"jenkins-ci-steemit\" }" rm -rf $WORKSPACE/* +# make docker cleanup after itself and delete all exited containers +sudo docker rm -v $(docker ps -a -q -f status=exited) || true diff --git a/ciscripts/buildpending.sh b/ciscripts/buildpending.sh index 69db4e9e13..58f2309939 100755 --- a/ciscripts/buildpending.sh +++ b/ciscripts/buildpending.sh @@ -2,5 +2,6 @@ curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ \"state\": \"pending\", \"target_url\": \"${BUILD_URL}\", - \"description\": \"The build is now pending in jenkinsci!\" + \"description\": \"The build is now pending in jenkinsci!\", + \"context\": \"jenkins-ci-steemit\" }" diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index b96c648a4b..22f5f5c149 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -1,5 +1,8 @@ #!/bin/bash export IMAGE_NAME="steemit/steem:${GIT_BRANCH#*/}" +if [[ $IMAGE_NAME == "steemit/steem:stable" ]] ; then + IMAGE_NAME="steemit/steem:latest" +fi sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME diff --git a/ciscripts/buildsuccess.sh b/ciscripts/buildsuccess.sh index d8ae62c641..601021e59e 100755 --- a/ciscripts/buildsuccess.sh +++ b/ciscripts/buildsuccess.sh @@ -3,6 +3,9 @@ curl -XPOST -H "Authorization: token $GITHUB_SECRET" https://api.github.com/repos/steemit/steem/statuses/$(git rev-parse HEAD) -d "{ \"state\": \"success\", \"target_url\": \"${BUILD_URL}\", - \"description\": \"Jenkins-CI reports build succeeded!!\" + \"description\": \"Jenkins-CI reports build succeeded!!\", + \"context\": \"jenkins-ci-steemit\" }" rm -rf $WORKSPACE/* +# make docker cleanup after itself and delete all exited containers +sudo docker rm -v $(docker ps -a -q -f status=exited) || true From e00d2d8e1bd036bef61ca1c91fc9c110fd6b8c7c Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 9 Dec 2016 12:30:31 -0500 Subject: [PATCH 30/77] Adds code coverage to automatic CI --- CMakeLists.txt | 2 ++ Dockerfile | 26 ++++++++++++++++++++++++++ tests/tests/operation_time_tests.cpp | 3 +++ 3 files changed, 31 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae6da30c04..acedfa5beb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,6 +175,8 @@ else( WIN32 ) # Apple AND Linux endif() endif() + set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") + # based on http://www.delorie.com/gnu/docs/gdb/gdb_70.html # uncomment this line to tell GDB about macros (slows compile times) # set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-2 -g3" ) diff --git a/Dockerfile b/Dockerfile index b85581b35c..f65d120161 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,6 +21,7 @@ RUN \ pbzip2 \ python3 \ python3-dev \ + lcov \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* @@ -45,6 +46,30 @@ RUN \ programs/build_helpers/check_reflect.py && \ rm -rf /usr/local/src/steem/build +RUN \ + cd /usr/local/src/steem && \ + git submodule update --init --recursive && \ + mkdir build && \ + cd build && \ + cmake \ + -DCMAKE_BUILD_TYPE=Debug \ + -DENABLE_COVERAGE_TESTING=ON \ + -DBUILD_STEEM_TESTNET=ON \ + -DLOW_MEMORY_NODE=OFF \ + -DCLEAR_VOTES=ON \ + .. && \ + make -j$(nproc) chain_test && \ + cd .. && \ + lcov --capture --initial --directory . --output-file build/base.info --no-external && \ + ./build/tests/chain_test && \ + lcov --capture --directory . --output-file build/test.info --no-external && \ + lcov --add-tracefile build/base.info --add-tracefile build/test.info --output-file build/total.info && \ + lcov -o build/interesting.info -r build/total.info tests/\* &&\ + mkdir -p /var/jenkins_home/lcov && \ + genhtml build/interesting.info --output-directory /var/jenkins_home/lcov && \ + cd /usr/local/src/steem && \ + rm -rf /usr/local/src/steem/build + RUN \ cd /usr/local/src/steem && \ git submodule update --init --recursive && \ @@ -114,6 +139,7 @@ RUN \ python-dev \ python2.7-dev \ python3-dev \ + lcov \ && \ apt-get autoremove -y && \ rm -rf \ diff --git a/tests/tests/operation_time_tests.cpp b/tests/tests/operation_time_tests.cpp index d54bf62c6a..1190b8342c 100644 --- a/tests/tests/operation_time_tests.cpp +++ b/tests/tests/operation_time_tests.cpp @@ -2426,6 +2426,8 @@ BOOST_AUTO_TEST_CASE( comment_freeze ) FC_LOG_AND_RETHROW() } +// This test is too intensive without optimizations. Disable it when we build in debug +#ifndef DEBUG BOOST_AUTO_TEST_CASE( sbd_stability ) { try @@ -2568,6 +2570,7 @@ BOOST_AUTO_TEST_CASE( sbd_stability ) } FC_LOG_AND_RETHROW() } +#endif BOOST_AUTO_TEST_CASE( sbd_price_feed_limit ) { From 01e6bee3988a8da0149ff49f0bb2c16bb608d70f Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 16 Dec 2016 14:47:40 -0500 Subject: [PATCH 31/77] Use gcovr for code coverage integration with Jenkins --- Dockerfile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index f65d120161..ea3f3102a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,10 +21,11 @@ RUN \ pbzip2 \ python3 \ python3-dev \ - lcov \ + python3-pip \ && \ apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ + pip3 install gcovr ADD . /usr/local/src/steem @@ -48,6 +49,7 @@ RUN \ RUN \ cd /usr/local/src/steem && \ + export LANG=en_US.UTF-8 && \ git submodule update --init --recursive && \ mkdir build && \ cd build && \ @@ -59,14 +61,9 @@ RUN \ -DCLEAR_VOTES=ON \ .. && \ make -j$(nproc) chain_test && \ - cd .. && \ - lcov --capture --initial --directory . --output-file build/base.info --no-external && \ - ./build/tests/chain_test && \ - lcov --capture --directory . --output-file build/test.info --no-external && \ - lcov --add-tracefile build/base.info --add-tracefile build/test.info --output-file build/total.info && \ - lcov -o build/interesting.info -r build/total.info tests/\* &&\ - mkdir -p /var/jenkins_home/lcov && \ - genhtml build/interesting.info --output-directory /var/jenkins_home/lcov && \ + ./tests/chain_test && \ + mkdir -p /var/jenkins_home/cobertura && \ + gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude="./tests" --output="/var/jenkins_home/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From c01cd25111f8ce3d3dae4fb3df8ebccdde3bd552 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 8 Dec 2016 13:07:57 -0500 Subject: [PATCH 32/77] Filter universal tag from reported tags and then filter by safe for work #673 --- libraries/plugins/tags/tags_plugin.cpp | 31 +++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index 33c2d573d2..5900fb45d3 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -189,31 +189,30 @@ struct operation_visitor { } set< string > lower_tags; + meta.tags.insert( fc::to_lower( to_string( c.category ) ) ); + + uint8_t tag_limit = 5; + uint8_t count = 0; for( const auto& tag : meta.tags ) + { + ++count; + if( count > tag_limit || lower_tags.size() > tag_limit ) + break; + if( tag == "" ) + continue; lower_tags.insert( fc::to_lower( tag ) ); + } - lower_tags.insert( fc::to_lower( to_string( c.category ) ) ); - - - bool safe_for_work = false; - /// the universal tag applies to everything safe for work or nsfw with a positive payout + /// the universal tag applies to everything safe for work or nsfw with a non-negative payout if( c.net_rshares >= 0 || - (lower_tags.find( "spam" ) == lower_tags.end() && - lower_tags.find( "nsfw" ) == lower_tags.end() && - lower_tags.find( "test" ) == lower_tags.end() ) ) + (lower_tags.find( "spam" ) == lower_tags.end() && + lower_tags.find( "nsfw" ) == lower_tags.end() && + lower_tags.find( "test" ) == lower_tags.end() ) ) { - safe_for_work = true; lower_tags.insert( string() ); /// add it to the universal tag } meta.tags = lower_tags; /// TODO: std::move??? - if( meta.tags.size() > 5 ) { - //wlog( "ignoring post ${a} because it has ${n} tags",("a", c.author + "/"+c.permlink)("n",meta.tags.size())); - if( safe_for_work ) - meta.tags = set< string >( {"", to_string( c.parent_permlink ) } ); - else - meta.tags.clear(); - } const auto& comment_idx = _db.get_index< tag_index >().indices().get< by_comment >(); From 7b8527e2d4a03f7fbea0f2eca1f9795d1187c248 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 9 Dec 2016 13:26:54 -0500 Subject: [PATCH 33/77] Update filtering #273 --- libraries/plugins/tags/tags_plugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index 5900fb45d3..9bf279aca4 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -189,7 +189,8 @@ struct operation_visitor { } set< string > lower_tags; - meta.tags.insert( fc::to_lower( to_string( c.category ) ) ); + if( c.category != "" ) + meta.tags.insert( fc::to_lower( to_string( c.category ) ) ); uint8_t tag_limit = 5; uint8_t count = 0; @@ -204,10 +205,9 @@ struct operation_visitor { } /// the universal tag applies to everything safe for work or nsfw with a non-negative payout - if( c.net_rshares >= 0 || + if( c.net_rshares >= 0 && (lower_tags.find( "spam" ) == lower_tags.end() && - lower_tags.find( "nsfw" ) == lower_tags.end() && - lower_tags.find( "test" ) == lower_tags.end() ) ) + lower_tags.find( "test" ) == lower_tags.end() ) ) { lower_tags.insert( string() ); /// add it to the universal tag } From 1ec35cabe99ed8f2e7dc957f9d8e8034dd5173cc Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 15 Dec 2016 11:08:10 -0500 Subject: [PATCH 34/77] Revert automatic filtering of down voted content. #673 --- libraries/plugins/tags/tags_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index 9bf279aca4..ef367c9105 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -205,7 +205,7 @@ struct operation_visitor { } /// the universal tag applies to everything safe for work or nsfw with a non-negative payout - if( c.net_rshares >= 0 && + if( c.net_rshares >= 0 || (lower_tags.find( "spam" ) == lower_tags.end() && lower_tags.find( "test" ) == lower_tags.end() ) ) { From 71aa2c0a5174869c45337ceb7831fac766ea78bb Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 1 Dec 2016 22:09:17 -0500 Subject: [PATCH 35/77] Add get_ops_in_block method to database API --- libraries/app/database_api.cpp | 26 +++++++++++++++++++ libraries/app/impacted.cpp | 1 + .../app/include/steemit/app/database_api.hpp | 9 +++++++ .../wallet/include/steemit/wallet/wallet.hpp | 8 ++++++ libraries/wallet/wallet.cpp | 5 ++++ 5 files changed, 49 insertions(+) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index d4017fb108..56a7c7941d 100755 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -39,6 +39,7 @@ class database_api_impl : public std::enable_shared_from_this // Blocks and transactions optional get_block_header(uint32_t block_num)const; optional get_block(uint32_t block_num)const; + vector get_ops_in_block(uint32_t block_num, bool only_virtual)const; // Globals fc::variant_object get_config()const; @@ -249,6 +250,31 @@ optional database_api_impl::get_block(uint32_t block_num)const return _db.fetch_block_by_number(block_num); } +vector database_api::get_ops_in_block(uint32_t block_num, bool only_virtual)const +{ + return my->_db.with_read_lock( [&]() + { + return my->get_ops_in_block( block_num, only_virtual ); + }); +} + +vector database_api_impl::get_ops_in_block(uint32_t block_num, bool only_virtual)const +{ + const auto& idx = _db.get_index< operation_index >().indices().get< by_location >(); + auto itr = idx.lower_bound( block_num ); + vector result; + applied_operation temp; + while( itr != idx.end() && itr->block == block_num ) + { + temp = *itr; + if( !only_virtual || is_virtual_operation(temp.op) ) + result.push_back(temp); + ++itr; + } + return result; +} + + ////////////////////////////////////////////////////////////////////// // // // Globals // diff --git a/libraries/app/impacted.cpp b/libraries/app/impacted.cpp index 7c9a3b8b74..231ec5523b 100644 --- a/libraries/app/impacted.cpp +++ b/libraries/app/impacted.cpp @@ -43,6 +43,7 @@ struct get_impacted_account_visitor template void operator()( const T& op ) { + op.get_required_posting_authorities( _impacted ); op.get_required_active_authorities( _impacted ); op.get_required_owner_authorities( _impacted ); } diff --git a/libraries/app/include/steemit/app/database_api.hpp b/libraries/app/include/steemit/app/database_api.hpp index b87dee1a74..622a5ea4bc 100755 --- a/libraries/app/include/steemit/app/database_api.hpp +++ b/libraries/app/include/steemit/app/database_api.hpp @@ -154,6 +154,14 @@ class database_api */ optional get_block(uint32_t block_num)const; + /** + * @brief Get sequence of operations included/generated within a particular block + * @param block_num Height of the block whose generated virtual operations should be returned + * @param only_virtual Whether to only include virtual operations in returned results (default: true) + * @return sequence of operations included/generated within the block + */ + vector get_ops_in_block(uint32_t block_num, bool only_virtual = true)const; + ///////////// // Globals // ///////////// @@ -462,6 +470,7 @@ FC_API(steemit::app::database_api, // Blocks and transactions (get_block_header) (get_block) + (get_ops_in_block) (get_state) (get_trending_categories) (get_best_categories) diff --git a/libraries/wallet/include/steemit/wallet/wallet.hpp b/libraries/wallet/include/steemit/wallet/wallet.hpp index 653b431313..a43a9cf6e0 100644 --- a/libraries/wallet/include/steemit/wallet/wallet.hpp +++ b/libraries/wallet/include/steemit/wallet/wallet.hpp @@ -128,6 +128,13 @@ class wallet_api */ optional get_block( uint32_t num ); + /** Returns sequence of operations included/generated in a specified block + * + * @param block_num Block height of specified block + * @param only_virtual Whether to only return virtual operations + */ + vector get_ops_in_block( uint32_t block_num, bool only_virtual = true ); + /** Return the current price feed history * * @returns Price feed history data on the blockchain @@ -958,6 +965,7 @@ FC_API( steemit::wallet::wallet_api, (get_witness) (get_account) (get_block) + (get_ops_in_block) (get_feed_history) (get_conversion_requests) (get_account_history) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index c0ddf6eb24..b4718cecc2 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -989,6 +989,11 @@ optional wallet_api::get_block(uint32_t num) return my->_remote_db->get_block(num); } +vector wallet_api::get_ops_in_block(uint32_t block_num, bool only_virtual) +{ + return my->_remote_db->get_ops_in_block(block_num, only_virtual); +} + vector wallet_api::list_my_accounts() { FC_ASSERT( !is_locked(), "Wallet must be unlocked to list accounts" ); From cf5dfdf17c735f1fd2544d513b7b30eecfb1f9ac Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 15 Dec 2016 11:07:14 -0500 Subject: [PATCH 36/77] Detect bug when writing to block log --- libraries/chain/database.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index db53cb80e0..acdcbf33df 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -3535,7 +3535,9 @@ void database::update_last_irreversible_block() { while( log_head_num < dpo.last_irreversible_block_num ) { - _block_log.append( *fetch_block_by_number( log_head_num + 1 ) ); + auto b = fetch_block_by_number( log_head_num + 1 ); + FC_ASSERT( b.valid() ); + _block_log.append( *b ); log_head_num++; } From 993c06fec758129cf8e6b67e09d15a12dbe95bec Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 15 Dec 2016 16:15:53 -0500 Subject: [PATCH 37/77] Fix block log error #675 --- libraries/chain/database.cpp | 66 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index acdcbf33df..0460309c30 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -224,9 +224,9 @@ void database::close(bool rewind) } bool database::is_known_block( const block_id_type& id )const -{ +{ try { return fetch_block_by_id( id ).valid(); -} +} FC_CAPTURE_AND_RETHROW() } /** * Only return true *if* the transaction has not expired or been invalidated. If this @@ -234,10 +234,10 @@ bool database::is_known_block( const block_id_type& id )const * query things by blocks if they are that old. */ bool database::is_known_transaction( const transaction_id_type& id )const -{ +{ try { const auto& trx_idx = get_index().indices().get(); return trx_idx.find( id ) != trx_idx.end(); -} +} FC_CAPTURE_AND_RETHROW() } block_id_type database::get_block_id_for_num( uint32_t block_num )const { @@ -256,7 +256,7 @@ block_id_type database::get_block_id_for_num( uint32_t block_num )const } optional database::fetch_block_by_id( const block_id_type& id )const -{ +{ try { auto b = _fork_db.fetch_block( id ); if( !b ) { @@ -270,10 +270,10 @@ optional database::fetch_block_by_id( const block_id_type& id )con } return b->data; -} +} FC_CAPTURE_AND_RETHROW() } optional database::fetch_block_by_number( uint32_t block_num )const -{ +{ try { optional< signed_block > b; auto results = _fork_db.fetch_block_by_number( block_num ); @@ -283,20 +283,20 @@ optional database::fetch_block_by_number( uint32_t block_num )cons b = _block_log.read_block_by_num( block_num ); return b; -} +} FC_LOG_AND_RETHROW() } const signed_transaction database::get_recent_transaction( const transaction_id_type& trx_id ) const -{ +{ try { auto& index = get_index().indices().get(); auto itr = index.find(trx_id); FC_ASSERT(itr != index.end()); signed_transaction trx; fc::raw::unpack( itr->packed_trx, trx ); return trx;; -} +} FC_CAPTURE_AND_RETHROW() } std::vector< block_id_type > database::get_block_ids_on_fork( block_id_type head_of_fork ) const -{ +{ try { pair branches = _fork_db.fetch_branch_from(head_block_id(), head_of_fork); if( !((branches.first.back()->previous_id() == branches.second.back()->previous_id())) ) { @@ -311,7 +311,7 @@ std::vector< block_id_type > database::get_block_ids_on_fork( block_id_type head result.emplace_back(fork_block->id); result.emplace_back(branches.first.back()->previous_id()); return result; -} +} FC_CAPTURE_AND_RETHROW() } chain_id_type database::get_chain_id() const { @@ -449,7 +449,7 @@ void database::pay_fee( const account_object& account, asset fee ) } void database::update_account_bandwidth( const account_object& a, uint32_t trx_size ) -{ +{ try { const auto& props = get_dynamic_global_properties(); if( props.total_vesting_shares.amount > 0 ) { @@ -497,11 +497,11 @@ void database::update_account_bandwidth( const account_object& a, uint32_t trx_s acnt.last_bandwidth_update = now; } ); } -} +} FC_CAPTURE_AND_RETHROW() } void database::update_account_market_bandwidth( const account_object& a, uint32_t trx_size ) -{ +{ try { const auto& props = get_dynamic_global_properties(); if( props.total_vesting_shares.amount > 0 ) { @@ -547,7 +547,7 @@ void database::update_account_market_bandwidth( const account_object& a, uint32_ acnt.last_market_bandwidth_update = now; } ); } -} +} FC_CAPTURE_AND_RETHROW() } uint32_t database::witness_participation_rate()const { @@ -601,7 +601,7 @@ bool database::push_block(const signed_block& new_block, uint32_t skip) } bool database::_push_block(const signed_block& new_block) -{ +{ try { uint32_t skip = get_node_properties().skip_flags; //uint32_t skip_undo_db = skip & skip_undo_block; @@ -680,7 +680,7 @@ bool database::_push_block(const signed_block& new_block) } return false; -} +} FC_CAPTURE_AND_RETHROW() } /** * Attempts to push the transaction into the pending queue @@ -2983,7 +2983,7 @@ void database::apply_block( const signed_block& next_block, uint32_t skip ) void database::_apply_block( const signed_block& next_block ) { try { uint32_t next_block_num = next_block.block_num(); - block_id_type next_block_id = next_block.id(); + //block_id_type next_block_id = next_block.id(); uint32_t skip = get_node_properties().skip_flags; @@ -3048,11 +3048,11 @@ void database::_apply_block( const signed_block& next_block ) ++_current_trx_in_block; } + update_last_irreversible_block(); + update_global_dynamic_data(next_block); update_signing_witness(signing_witness, next_block); - update_last_irreversible_block(); - create_block_summary(next_block); clear_expired_transactions(); clear_expired_orders(); @@ -3306,7 +3306,7 @@ void database::apply_operation(const operation& op) } const witness_object& database::validate_block_header( uint32_t skip, const signed_block& next_block )const -{ +{ try { FC_ASSERT( head_block_id() == next_block.previous, "", ("head_block_id",head_block_id())("next.prev",next_block.previous) ); FC_ASSERT( head_block_time() < next_block.timestamp, "", ("head_block_time",head_block_time())("next",next_block.timestamp)("blocknum",next_block.block_num()) ); const witness_object& witness = get_witness( next_block.witness ); @@ -3326,18 +3326,18 @@ const witness_object& database::validate_block_header( uint32_t skip, const sign } return witness; -} +} FC_CAPTURE_AND_RETHROW() } void database::create_block_summary(const signed_block& next_block) -{ +{ try { block_summary_id_type sid( next_block.block_num() & 0xffff ); modify( get< block_summary_object >( sid ), [&](block_summary_object& p) { p.block_id = next_block.id(); }); -} +} FC_CAPTURE_AND_RETHROW() } void database::update_global_dynamic_data( const signed_block& b ) -{ +{ try { auto block_size = fc::raw::pack_size(b); const dynamic_global_property_object& _dgp = get_dynamic_global_properties(); @@ -3432,10 +3432,10 @@ void database::update_global_dynamic_data( const signed_block& b ) //_undo_db.set_max_size( _dgp.head_block_number - _dgp.last_irreversible_block_num + 1 ); _fork_db.set_max_size( _dgp.head_block_number - _dgp.last_irreversible_block_num + 1 ); -} +} FC_CAPTURE_AND_RETHROW() } void database::update_virtual_supply() -{ +{ try { modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgp ) { dgp.virtual_supply = dgp.current_supply @@ -3456,10 +3456,10 @@ void database::update_virtual_supply() dgp.sbd_print_rate = ( ( STEEMIT_SBD_STOP_PERCENT - percent_sbd ) * STEEMIT_100_PERCENT ) / ( STEEMIT_SBD_STOP_PERCENT - STEEMIT_SBD_START_PERCENT ); } }); -} +} FC_CAPTURE_AND_RETHROW() } void database::update_signing_witness(const witness_object& signing_witness, const signed_block& new_block) -{ +{ try { const dynamic_global_property_object& dpo = get_dynamic_global_properties(); uint64_t new_block_aslot = dpo.current_aslot + get_slot_at_time( new_block.timestamp ); @@ -3468,10 +3468,10 @@ void database::update_signing_witness(const witness_object& signing_witness, con _wit.last_aslot = new_block_aslot; _wit.last_confirmed_block_num = new_block.block_num(); } ); -} +} FC_CAPTURE_AND_RETHROW() } void database::update_last_irreversible_block() -{ +{ try { const dynamic_global_property_object& dpo = get_dynamic_global_properties(); /** @@ -3544,7 +3544,7 @@ void database::update_last_irreversible_block() _block_log.flush(); } } -} +} FC_CAPTURE_AND_RETHROW() } bool database::apply_order( const limit_order_object& new_order_object ) From b948c5a01f51429ba0e377aee8e2d5f493255d2d Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 16 Dec 2016 12:35:55 -0500 Subject: [PATCH 38/77] Progress on bug fix --- libraries/chain/database.cpp | 11 +++++------ libraries/chain/fork_database.cpp | 16 +++------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 0460309c30..a6b2a94151 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -3048,11 +3048,11 @@ void database::_apply_block( const signed_block& next_block ) ++_current_trx_in_block; } - update_last_irreversible_block(); - update_global_dynamic_data(next_block); update_signing_witness(signing_witness, next_block); + update_last_irreversible_block(); + create_block_summary(next_block); clear_expired_transactions(); clear_expired_orders(); @@ -3429,9 +3429,6 @@ void database::update_global_dynamic_data( const signed_block& b ) ("last_irreversible_block_num",_dgp.last_irreversible_block_num)("head", _dgp.head_block_number) ("max_undo",STEEMIT_MAX_UNDO_HISTORY) ); } - - //_undo_db.set_max_size( _dgp.head_block_number - _dgp.last_irreversible_block_num + 1 ); - _fork_db.set_max_size( _dgp.head_block_number - _dgp.last_irreversible_block_num + 1 ); } FC_CAPTURE_AND_RETHROW() } void database::update_virtual_supply() @@ -3536,7 +3533,7 @@ void database::update_last_irreversible_block() while( log_head_num < dpo.last_irreversible_block_num ) { auto b = fetch_block_by_number( log_head_num + 1 ); - FC_ASSERT( b.valid() ); + FC_ASSERT( b.valid(), "", ("log_head", log_head_num)("last_irreversible_block_num", dpo.last_irreversible_block_num)("head_block",head_block_num())("fork_db_size", _fork_db._max_size) ); _block_log.append( *b ); log_head_num++; } @@ -3544,6 +3541,8 @@ void database::update_last_irreversible_block() _block_log.flush(); } } + + _fork_db.set_max_size( dpo.head_block_number - dpo.last_irreversible_block_num + 1 ); } FC_CAPTURE_AND_RETHROW() } diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index 9276b64ba0..8d289942c1 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -67,19 +67,7 @@ void fork_database::_push_block(const item_ptr& item) } _index.insert(item); - if( !_head ) _head = item; - else if( item->num > _head->num ) - { - _head = item; - uint32_t min_num = _head->num - std::min( _max_size, _head->num ); -// ilog( "min block in fork DB ${n}, max_size: ${m}", ("n",min_num)("m",_max_size) ); - auto& num_idx = _index.get(); - while( num_idx.size() && (*num_idx.begin())->num < min_num ) - num_idx.erase( num_idx.begin() ); - - _unlinked_index.get().erase(_head->num - _max_size); - } - //_push_next( item ); + if( !_head || item->num > _head->num ) _head = item; } /** @@ -108,6 +96,8 @@ void fork_database::set_max_size( uint32_t s ) _max_size = s; if( !_head ) return; + ilog( "Deleting blocks with num less than ${n}", ("n", std::max(int64_t(0),int64_t(_head->num) - _max_size)) ); + { /// index auto& by_num_idx = _index.get(); auto itr = by_num_idx.begin(); From 551062f1156f4d408b836664ba31e77bb22e10f0 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 16 Dec 2016 14:46:15 -0500 Subject: [PATCH 39/77] Block num fork resolution when writing to block log #675 --- libraries/chain/database.cpp | 18 +++++++++++++++--- libraries/chain/fork_database.cpp | 2 -- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index a6b2a94151..cdb72d1d8f 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -3532,9 +3532,21 @@ void database::update_last_irreversible_block() { while( log_head_num < dpo.last_irreversible_block_num ) { - auto b = fetch_block_by_number( log_head_num + 1 ); - FC_ASSERT( b.valid(), "", ("log_head", log_head_num)("last_irreversible_block_num", dpo.last_irreversible_block_num)("head_block",head_block_num())("fork_db_size", _fork_db._max_size) ); - _block_log.append( *b ); + signed_block b; + auto blocks = _fork_db.fetch_block_by_number( log_head_num + 1 ); + + if( blocks.size() == 1 ) + b = blocks[0]->data; + else + { + auto next = _fork_db.head(); + while( next->num > log_head_num + 1 ) + next = next->prev.lock(); + + b = next->data; + } + + _block_log.append( b ); log_head_num++; } diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index 8d289942c1..3a5d9b1b07 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -96,8 +96,6 @@ void fork_database::set_max_size( uint32_t s ) _max_size = s; if( !_head ) return; - ilog( "Deleting blocks with num less than ${n}", ("n", std::max(int64_t(0),int64_t(_head->num) - _max_size)) ); - { /// index auto& by_num_idx = _index.get(); auto itr = by_num_idx.begin(); From 76050f697414b9a59d76505e3bfb13b94bcd579a Mon Sep 17 00:00:00 2001 From: Xeldal Date: Sat, 17 Dec 2016 06:51:19 -0500 Subject: [PATCH 40/77] Update seednodes.txt (#709) --- doc/seednodes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/seednodes.txt b/doc/seednodes.txt index 95e49e2868..4e95655f69 100644 --- a/doc/seednodes.txt +++ b/doc/seednodes.txt @@ -7,7 +7,7 @@ steemd.pharesim.me:2001 # pharesim seed.jesta.us:2001 # jesta 212.117.213.186:2016 # liondani anyx.co:2001 # anyx -45.55.217.111:12150 # xeldal +seed.xeldal.com:12150 # xeldal seed.steemnodes.com:2001 # wackou steem.clawmap.com:2001 # steempty gtg.steem.house:2001 # gtg From 7471b7458ed5842d164c7142ef05d1d9bda0425f Mon Sep 17 00:00:00 2001 From: bitcoiner Date: Sat, 17 Dec 2016 19:53:21 +0800 Subject: [PATCH 41/77] Added seed node (#580) --- doc/seednodes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/seednodes.txt b/doc/seednodes.txt index 4e95655f69..be88b3d0b3 100644 --- a/doc/seednodes.txt +++ b/doc/seednodes.txt @@ -26,6 +26,7 @@ steem.global:2001 # klye seed.royaltiffany.me:2001 # royaltiffany 129.232.223.74:2001 # thecryptodrive steem-id.altexplorer.xyz:2001 # steem-id +seed.bitcoiner.me:2001 # bitcoiner 52.26.78.244:2001 # ? 52.37.169.52:2001 # ? 52.38.66.234:2001 # ? From f4c6273027524cf4535e04603a4b69582f18d8b3 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Mon, 19 Dec 2016 11:56:33 -0500 Subject: [PATCH 42/77] Remove obsolete blockchain startup message #711 --- libraries/plugins/witness/witness.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/plugins/witness/witness.cpp b/libraries/plugins/witness/witness.cpp index 01908b0fdd..4f3069876e 100644 --- a/libraries/plugins/witness/witness.cpp +++ b/libraries/plugins/witness/witness.cpp @@ -55,13 +55,6 @@ void new_chain_banner( const steemit::chain::database& db ) "* *\n" "********************************\n" "\n"; - if( db.get_slot_at_time( graphene::time::now() ) > 200 ) - { - std::cerr << "Your genesis seems to have an old timestamp\n" - "Please consider using the --genesis-timestamp option to give your genesis a recent timestamp\n" - "\n" - ; - } return; } From 66780a9d81bec4b27c2211f75896109e8aafd7ca Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 19 Dec 2016 13:54:10 -0500 Subject: [PATCH 43/77] Set LANG as Docker ENV and remove specific reference to Jenkins in coverage location. (Jenkins can knowledgably map the file to the correct location) --- Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ea3f3102a2..ceabad4140 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,8 @@ FROM phusion/baseimage:0.9.19 #ARG STEEMD_BLOCKCHAIN=https://example.com/steemd-blockchain.tbz2 +ENV LANG=en_US.UTF-8 + RUN \ apt-get update && \ apt-get install -y \ @@ -49,7 +51,6 @@ RUN \ RUN \ cd /usr/local/src/steem && \ - export LANG=en_US.UTF-8 && \ git submodule update --init --recursive && \ mkdir build && \ cd build && \ @@ -62,8 +63,8 @@ RUN \ .. && \ make -j$(nproc) chain_test && \ ./tests/chain_test && \ - mkdir -p /var/jenkins_home/cobertura && \ - gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude="./tests" --output="/var/jenkins_home/cobertura/coverage.xml" && \ + mkdir -p /var/cobertura && \ + gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude="./tests" --output="/var/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From 93bbdedc3256fb086cdc24dcc8f94b83dd625b0d Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Mon, 19 Dec 2016 15:40:51 -0500 Subject: [PATCH 44/77] Add pkg-config to Dockerfile, docs #715 --- Dockerfile | 1 + doc/building.md | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b85581b35c..22638bb984 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ RUN \ libtool \ ncurses-dev \ pbzip2 \ + pkg-config \ python3 \ python3-dev \ && \ diff --git a/doc/building.md b/doc/building.md index a23cf35e8d..b02cc81db2 100644 --- a/doc/building.md +++ b/doc/building.md @@ -44,7 +44,8 @@ will build out of the box without further effort: git \ libssl-dev \ libtool \ - make + make \ + pkg-config # Boost packages (also required) sudo apt-get install -y \ @@ -92,7 +93,8 @@ Here are the required packages: git \ libssl-dev \ libtool \ - make + make \ + pkg-config # Packages required to build Boost sudo apt-get install -y \ From 19c266e7320220b57fa9476abf1bd8fdb7b13c4c Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Wed, 14 Dec 2016 11:29:33 -0500 Subject: [PATCH 45/77] Replace switch(which()) with visitor #702 --- libraries/protocol/steem_operations.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libraries/protocol/steem_operations.cpp b/libraries/protocol/steem_operations.cpp index 491e5a5c32..5d00f73c5e 100644 --- a/libraries/protocol/steem_operations.cpp +++ b/libraries/protocol/steem_operations.cpp @@ -198,21 +198,22 @@ namespace steemit { namespace protocol { FC_ASSERT( work_input() == work.input, "Determninistic input does not match recorded input" ); work.validate(); } - void pow2_operation::validate()const + + struct pow2_operation_validate_visitor { - props.validate(); - switch( work.which() ) + typedef void result_type; + + template< typename PowType > + void operator()( const PowType& pow )const { - case pow2_work::tag< pow2 >::value: - work.get< pow2 >().validate(); - break; - case pow2_work::tag< equihash_pow >::value: - work.get< equihash_pow >().validate(); - break; - default: - FC_ASSERT( false, "POW2 Operation does not contain a proof of work" ); - break; + pow.validate(); } + }; + + void pow2_operation::validate()const + { + props.validate(); + work.visit( pow2_operation_validate_visitor() ); } void pow::create( const fc::ecc::private_key& w, const digest_type& i ) From a42bf347731d3a17ee66c029cc29b4895205a61f Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 15 Dec 2016 14:15:04 -0500 Subject: [PATCH 46/77] Log hardforks for testnet nodes #710 --- libraries/chain/database.cpp | 74 +++++++------------ .../chain/include/steemit/chain/database.hpp | 2 + tests/common/database_fixture.cpp | 1 + tests/tests/block_tests.cpp | 10 +++ 4 files changed, 38 insertions(+), 49 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index db53cb80e0..6a474067b8 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -4026,12 +4026,18 @@ void database::set_hardfork( uint32_t hardfork, bool apply_now ) void database::apply_hardfork( uint32_t hardfork ) { + auto log_hardfork = [this]( int hf ) + { + if( _log_hardforks ) + { + elog( "HARDFORK ${hf} at block ${b}", ("hf", hf)("b", head_block_num()) ); + } + }; + switch( hardfork ) { case STEEMIT_HARDFORK_0_1: -#ifndef IS_TEST_NET - elog( "HARDFORK 1 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(1); perform_vesting_share_split( 1000000 ); #ifdef IS_TEST_NET { @@ -4048,50 +4054,34 @@ void database::apply_hardfork( uint32_t hardfork ) #endif break; case STEEMIT_HARDFORK_0_2: -#ifndef IS_TEST_NET - elog( "HARDFORK 2 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(2); retally_witness_votes(); break; case STEEMIT_HARDFORK_0_3: -#ifndef IS_TEST_NET - elog( "HARDFORK 3 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(3); retally_witness_votes(); break; case STEEMIT_HARDFORK_0_4: -#ifndef IS_TEST_NET - elog( "HARDFORK 4 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(4); reset_virtual_schedule_time(); break; case STEEMIT_HARDFORK_0_5: -#ifndef IS_TEST_NET - elog( "HARDFORK 5 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(5); break; case STEEMIT_HARDFORK_0_6: -#ifndef IS_TEST_NET - elog( "HARDFORK 6 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(6); retally_witness_vote_counts(); retally_comment_children(); break; case STEEMIT_HARDFORK_0_7: -#ifndef IS_TEST_NET - elog( "HARDFORK 7 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(7); break; case STEEMIT_HARDFORK_0_8: -#ifndef IS_TEST_NET - elog( "HARDFORK 8 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(8); retally_witness_vote_counts(true); break; case STEEMIT_HARDFORK_0_9: -#ifndef IS_TEST_NET - elog( "HARDFORK 9 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(9); { for( const std::string& acc : hardfork9::get_compromised_accounts() ) { @@ -4110,20 +4100,14 @@ void database::apply_hardfork( uint32_t hardfork ) } break; case STEEMIT_HARDFORK_0_10: -#ifndef IS_TEST_NET - elog( "HARDFORK 10 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(10); retally_liquidity_weight(); break; case STEEMIT_HARDFORK_0_11: -#ifndef IS_TEST_NET - elog( "HARDFORK 11 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(11); break; case STEEMIT_HARDFORK_0_12: -#ifndef IS_TEST_NET - elog( "HARDFORK 12 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(12); { const auto& comment_idx = get_index< comment_index >().indices(); @@ -4175,24 +4159,16 @@ void database::apply_hardfork( uint32_t hardfork ) } break; case STEEMIT_HARDFORK_0_13: -#ifndef IS_TEST_NET - elog( "HARDFORK 13 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(13); break; case STEEMIT_HARDFORK_0_14: -#ifndef IS_TEST_NET - elog( "HARDFORK 14 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(14); break; - case STEEMIT_HARDFORK_0_15: -#ifndef IS_TEST_NET - elog( "HARDFORK 15 at block ${b}", ("b", head_block_num()) ); -#endif + case STEEMIT_HARDFORK_0_15: + log_hardfork(15); break; case STEEMIT_HARDFORK_0_16: -#ifndef IS_TEST_NET - elog( "HARDFORK 16 at block ${b}", ("b", head_block_num()) ); -#endif + log_hardfork(16); modify( get_feed_history(), [&]( feed_history_object& fho ) { while( fho.price_history.size() > STEEMIT_FEED_HISTORY_WINDOW ) diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index d4af8723a5..3df2fb375d 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -44,6 +44,8 @@ namespace steemit { namespace chain { void set_producing( bool p ) { _is_producing = p; } bool _is_producing = false; + bool _log_hardforks = true; + enum validation_steps { skip_nothing = 0, diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 2a0b6da5dc..c2b8be4432 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -187,6 +187,7 @@ void database_fixture::open_database() { if( !data_dir ) { data_dir = fc::temp_directory( graphene::utilities::temp_directory_path() ); + db._log_hardforks = false; db.open( data_dir->path(), data_dir->path(), INITIAL_TEST_SUPPLY, 1024 * 1024 * 8, chainbase::database::read_write ); // 8 MB file for testing } } diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 6eaea93521..666c58dbac 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -58,6 +58,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) signed_block cutoff_block; { database db; + db._log_hardforks = false; db.open(data_dir.path(), data_dir.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); b = db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); @@ -84,6 +85,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) } { database db; + db._log_hardforks = false; db.open(data_dir.path(), data_dir.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); BOOST_CHECK_EQUAL( db.head_block_num(), cutoff_block.block_num() ); b = cutoff_block; @@ -109,6 +111,7 @@ BOOST_AUTO_TEST_CASE( undo_block ) fc::temp_directory data_dir( graphene::utilities::temp_directory_path() ); { database db; + db._log_hardforks = false; db.open(data_dir.path(), data_dir.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); fc::time_point_sec now( STEEMIT_TESTING_GENESIS_TIMESTAMP ); std::vector< time_point_sec > time_stack; @@ -160,8 +163,10 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) //TODO This test needs 6-7 ish witnesses prior to fork database db1; + db1._log_hardforks = false; db1.open( data_dir1.path(), data_dir1.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); database db2; + db2._log_hardforks = false; db2.open( data_dir2.path(), data_dir2.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("init_key")) ); @@ -223,7 +228,9 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create ) dir2( graphene::utilities::temp_directory_path() ); database db1, db2; + db1._log_hardforks = false; db1.open( dir1.path(), dir1.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); + db2._log_hardforks = false; db2.open( dir2.path(), dir2.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("init_key")) ); @@ -280,7 +287,9 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions ) dir2( graphene::utilities::temp_directory_path() ); database db1, db2; + db1._log_hardforks = false; db1.open(dir1.path(), dir1.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); + db2._log_hardforks = false; db2.open(dir2.path(), dir2.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); BOOST_CHECK( db1.get_chain_id() == db2.get_chain_id() ); @@ -330,6 +339,7 @@ BOOST_AUTO_TEST_CASE( tapos ) try { fc::temp_directory dir1( graphene::utilities::temp_directory_path() ); database db1; + db1._log_hardforks = false; db1.open(dir1.path(), dir1.path(), INITIAL_TEST_SUPPLY, TEST_SHARED_MEM_SIZE, chainbase::database::read_write ); auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("init_key")) ); From b427211d71c99adb24b3a61e4a879b6fe996f8e9 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 19 Dec 2016 16:01:35 -0500 Subject: [PATCH 47/77] Refer to block as a pointer. More defensive coding. --- libraries/chain/database.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index cdb72d1d8f..5460a2dd25 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -3532,21 +3532,24 @@ void database::update_last_irreversible_block() { while( log_head_num < dpo.last_irreversible_block_num ) { - signed_block b; + signed_block* block_ptr; auto blocks = _fork_db.fetch_block_by_number( log_head_num + 1 ); if( blocks.size() == 1 ) - b = blocks[0]->data; + block_ptr = &( blocks[0]->data ); else { + ilog( "Encountered a block num collision due to a fork. Walking the current fork to determine the correct block. block_num:${n}", ("n", log_head_num + 1) ); // TODO: Delete when we know this code works as intended auto next = _fork_db.head(); - while( next->num > log_head_num + 1 ) + while( next.get() != nullptr && next->num > log_head_num + 1 ) next = next->prev.lock(); - b = next->data; + FC_ASSERT( next.get() != nullptr, "Current fork in the fork database does not contain the last_irreversible_block" ); + + block_ptr = &( next->data ); } - _block_log.append( b ); + _block_log.append( *block_ptr ); log_head_num++; } From 22ea72b2f7c69aa515f572367d58ce8933002e23 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 1 Dec 2016 17:27:41 -0500 Subject: [PATCH 48/77] Move bandwidth fields from account object into their own objects --- .../include/steemit/app/steem_api_objects.hpp | 5 - libraries/chain/database.cpp | 108 ++++++------------ .../include/steemit/chain/account_object.hpp | 58 +++++++--- .../chain/include/steemit/chain/database.hpp | 3 +- .../steemit/chain/steem_object_types.hpp | 13 +++ libraries/chain/steem_evaluator.cpp | 4 +- libraries/chainbase | 2 +- 7 files changed, 90 insertions(+), 103 deletions(-) diff --git a/libraries/app/include/steemit/app/steem_api_objects.hpp b/libraries/app/include/steemit/app/steem_api_objects.hpp index 33ea085bf3..eec44c5cd9 100644 --- a/libraries/app/include/steemit/app/steem_api_objects.hpp +++ b/libraries/app/include/steemit/app/steem_api_objects.hpp @@ -231,11 +231,6 @@ struct account_api_obj withdraw_routes( a.withdraw_routes ), proxied_vsf_votes( a.proxied_vsf_votes.size() ), witnesses_voted_for( a.witnesses_voted_for ), - average_bandwidth( a.average_bandwidth ), - lifetime_bandwidth( a.lifetime_bandwidth ), - last_bandwidth_update( a.last_bandwidth_update ), - average_market_bandwidth( a.average_market_bandwidth ), - last_market_bandwidth_update( a.last_market_bandwidth_update ), last_post( a.last_post ), last_root_post( a.last_root_post ), post_bandwidth( a.post_bandwidth ) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index cdb72d1d8f..712041e4f3 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -448,104 +448,61 @@ void database::pay_fee( const account_object& account, asset fee ) adjust_supply( -fee ); } -void database::update_account_bandwidth( const account_object& a, uint32_t trx_size ) +void database::update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ) { try { const auto& props = get_dynamic_global_properties(); if( props.total_vesting_shares.amount > 0 ) { -#ifdef IS_TEST_NET - if( !skip_transaction_delta_check ) -#endif - // Soft fork to prevent multiple transactions for an account in the same block - FC_ASSERT( !is_producing() || a.last_bandwidth_update < head_block_time(), - "Account already transacted this block." ); + FC_ASSERT( a.vesting_shares.amount > 0, "Only accounts with a postive vesting balance may transact." ); - modify( a, [&]( account_object& acnt ) - { - acnt.lifetime_bandwidth += trx_size * STEEMIT_BANDWIDTH_PRECISION; - - auto now = head_block_time(); - auto delta_time = (now - a.last_bandwidth_update).to_seconds(); - uint64_t N = trx_size * STEEMIT_BANDWIDTH_PRECISION; - if( delta_time >= STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS ) - acnt.average_bandwidth = N; - else - { - auto old_weight = acnt.average_bandwidth * (STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS - delta_time); - auto new_weight = delta_time * N; - acnt.average_bandwidth = (old_weight + new_weight) / (STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS); - } + auto band = find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( a.name, type ) ); - if( props.total_vesting_shares.amount > 0 ) + if( band == nullptr ) + { + band = &create< account_bandwidth_object >( [&](account_bandwidth_object& b ) { - FC_ASSERT( a.vesting_shares.amount > 0, "only accounts with a positive vesting balance may transact" ); - - fc::uint128 account_vshares(a.vesting_shares.amount.value); - fc::uint128 total_vshares( props.total_vesting_shares.amount.value ); - - fc::uint128 account_average_bandwidth( acnt.average_bandwidth ); - fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth ); - - // account_vshares / total_vshares > account_average_bandwidth / max_virtual_bandwidth - FC_ASSERT( (account_vshares * max_virtual_bandwidth) > (account_average_bandwidth * total_vshares), - "account exceeded maximum allowed bandwidth per vesting share account_vshares: ${account_vshares} account_average_bandwidth: ${account_average_bandwidth} max_virtual_bandwidth: ${max_virtual_bandwidth} total_vesting_shares: ${total_vesting_shares}", - ("account_vshares",account_vshares) - ("account_average_bandwidth",account_average_bandwidth) - ("max_virtual_bandwidth",max_virtual_bandwidth) - ("total_vesting_shares",total_vshares) ); - } - acnt.last_bandwidth_update = now; - } ); - } -} FC_CAPTURE_AND_RETHROW() } - - -void database::update_account_market_bandwidth( const account_object& a, uint32_t trx_size ) -{ try { - const auto& props = get_dynamic_global_properties(); - if( props.total_vesting_shares.amount > 0 ) - { + b.account = a.name; + b.type = type; + }); + } #ifdef IS_TEST_NET if( !skip_transaction_delta_check ) #endif // Soft fork to prevent multiple transactions for an account in the same block - FC_ASSERT( !is_producing() || a.last_market_bandwidth_update < head_block_time(), + FC_ASSERT( !is_producing() || band->last_bandwidth_update < head_block_time(), "Account already transacted this block." ); - modify( a, [&]( account_object& acnt ) + modify( *band, [&]( account_bandwidth_object& b ) { + b.lifetime_bandwidth += trx_size * STEEMIT_BANDWIDTH_PRECISION; + auto now = head_block_time(); - auto delta_time = (now - a.last_market_bandwidth_update).to_seconds(); + auto delta_time = (now - b.last_bandwidth_update).to_seconds(); uint64_t N = trx_size * STEEMIT_BANDWIDTH_PRECISION; if( delta_time >= STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS ) - acnt.average_market_bandwidth = N; + b.average_bandwidth = N; else { - auto old_weight = acnt.average_market_bandwidth * (STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS - delta_time); + auto old_weight = b.average_bandwidth * ( STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS - delta_time ); auto new_weight = delta_time * N; - acnt.average_market_bandwidth = (old_weight + new_weight) / (STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS); + b.average_bandwidth = ( old_weight + new_weight ) / STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS; } - if( props.total_vesting_shares.amount > 0 ) - { - FC_ASSERT( a.vesting_shares.amount > 0, "only accounts with a positive vesting balance may transact" ); + b.last_bandwidth_update = now; + }); - fc::uint128 account_vshares(a.vesting_shares.amount.value); - fc::uint128 total_vshares( props.total_vesting_shares.amount.value ); + fc::uint128 account_vshares( a.vesting_shares.amount.value ); + fc::uint128 total_vshares( props.total_vesting_shares.amount.value ); - fc::uint128 account_average_bandwidth( acnt.average_market_bandwidth ); - fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth / 10 ); /// only 10% of bandwidth can be market + fc::uint128 account_average_bandwidth( band->average_bandwidth.value ); + fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth ); - // account_vshares / total_vshares > account_average_bandwidth / max_virtual_bandwidth - FC_ASSERT( (account_vshares * max_virtual_bandwidth) > (account_average_bandwidth * total_vshares), - "account exceeded maximum allowed bandwidth per vesting share account_vshares: ${account_vshares} account_average_bandwidth: ${account_average_bandwidth} max_virtual_bandwidth: ${max_virtual_bandwidth} total_vesting_shares: ${total_vesting_shares}", - ("account_vshares",account_vshares) - ("account_average_bandwidth",account_average_bandwidth) - ("max_virtual_bandwidth",max_virtual_bandwidth) - ("total_vshares",total_vshares) ); - } - acnt.last_market_bandwidth_update = now; - } ); + FC_ASSERT( ( account_vshares * max_virtual_bandwidth ) > ( account_average_bandwidth * total_vshares ), + "Account exceeded maximum allowed bandwidth per vesting share.", + ("account_vshares", account_vshares) + ("account_average_bandwidth", account_average_bandwidth) + ("max_virtual_bandwidth", max_virtual_bandwidth) + ("total_vesting_shares", total_vshares) ); } } FC_CAPTURE_AND_RETHROW() } @@ -2659,6 +2616,7 @@ void database::initialize_indexes() add_core_index< dynamic_global_property_index >(*this); add_core_index< account_index >(*this); add_core_index< account_authority_index >(*this); + add_core_index< account_bandwidth_index >(*this); add_core_index< witness_index >(*this); add_core_index< transaction_index >(*this); add_core_index< block_summary_index >(*this); @@ -3241,11 +3199,11 @@ void database::_apply_transaction(const signed_transaction& trx) for( const auto& auth : required ) { const auto& acnt = get_account(auth); - update_account_bandwidth( acnt, trx_size ); + update_account_bandwidth( acnt, trx_size, bandwidth_type::forum ); for( const auto& op : trx.operations ) { if( is_market_operation( op ) ) { - update_account_market_bandwidth( get_account(auth), trx_size ); + update_account_bandwidth( acnt, trx_size, bandwidth_type::market ); break; } } diff --git a/libraries/chain/include/steemit/chain/account_object.hpp b/libraries/chain/include/steemit/chain/account_object.hpp index 2d2cd24a29..da02df637f 100644 --- a/libraries/chain/include/steemit/chain/account_object.hpp +++ b/libraries/chain/include/steemit/chain/account_object.hpp @@ -97,23 +97,6 @@ namespace steemit { namespace chain { uint16_t witnesses_voted_for = 0; - /** - * This field tracks the average bandwidth consumed by this account and gets updated every time a transaction - * is produced by this account using the following equation. It has units of micro-bytes-per-second. - * - * W = STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS = 1 week in seconds - * S = now - last_bandwidth_update - * N = fc::raw::packsize( transaction ) * 1,000,000 - * - * average_bandwidth = MIN(0,average_bandwidth * (W-S) / W) + N * S / W - * last_bandwidth_update = T + S - */ - uint64_t average_bandwidth = 0; - uint64_t lifetime_bandwidth = 0; - time_point_sec last_bandwidth_update; - - uint64_t average_market_bandwidth = 0; - time_point_sec last_market_bandwidth_update; time_point_sec last_post; time_point_sec last_root_post = fc::time_point_sec::min(); uint32_t post_bandwidth = 0; @@ -152,6 +135,24 @@ namespace steemit { namespace chain { time_point_sec last_owner_update; }; + class account_bandwidth_object : public object< account_bandwidth_object_type, account_bandwidth_object > + { + public: + template< typename Constructor, typename Allocator > + account_bandwidth_object( Constructor&& c, allocator< Allocator > a ) + { + c( *this ); + } + + id_type id; + + account_name_type account; + bandwidth_type type; + share_type average_bandwidth; + share_type lifetime_bandwidth; + time_point_sec last_bandwidth_update; + }; + class owner_authority_history_object : public object< owner_authority_history_object_type, owner_authority_history_object > { public: @@ -327,6 +328,23 @@ namespace steemit { namespace chain { > account_authority_index; + struct by_account_bandwidth_type; + + typedef multi_index_container < + account_bandwidth_object, + indexed_by < + ordered_unique< tag< by_id >, + member< account_bandwidth_object, account_bandwidth_id_type, &account_bandwidth_object::id > >, + ordered_unique< tag< by_account_bandwidth_type >, + composite_key< account_bandwidth_object, + member< account_bandwidth_object, account_name_type, &account_bandwidth_object::account >, + member< account_bandwidth_object, bandwidth_type, &account_bandwidth_object::type > + > + > + >, + allocator< account_bandwidth_object > + > account_bandwidth_index; + struct by_expiration; typedef multi_index_container < @@ -391,8 +409,6 @@ FC_REFLECT( steemit::chain::account_object, (curation_rewards) (posting_rewards) (proxied_vsf_votes)(witnesses_voted_for) - (average_bandwidth)(lifetime_bandwidth)(last_bandwidth_update) - (average_market_bandwidth)(last_market_bandwidth_update) (last_post)(last_root_post)(post_bandwidth) ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::account_object, steemit::chain::account_index ) @@ -402,6 +418,10 @@ FC_REFLECT( steemit::chain::account_authority_object, ) CHAINBASE_SET_INDEX_TYPE( steemit::chain::account_authority_object, steemit::chain::account_authority_index ) +FC_REFLECT( steemit::chain::account_bandwidth_object, + (id)(account)(type)(average_bandwidth)(lifetime_bandwidth)(last_bandwidth_update) ) +CHAINBASE_SET_INDEX_TYPE( steemit::chain::account_bandwidth_object, steemit::chain::account_bandwidth_index ) + FC_REFLECT( steemit::chain::owner_authority_history_object, (id)(account)(previous_owner_authority)(last_valid_time) ) diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index d4af8723a5..f4fef10e66 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -146,8 +146,7 @@ namespace steemit { namespace chain { * Deducts fee from the account and the share supply */ void pay_fee( const account_object& a, asset fee ); - void update_account_bandwidth( const account_object& a, uint32_t trx_size ); - void update_account_market_bandwidth( const account_object& a, uint32_t trx_size ); + void update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ); void max_bandwidth_per_share()const; diff --git a/libraries/chain/include/steemit/chain/steem_object_types.hpp b/libraries/chain/include/steemit/chain/steem_object_types.hpp index 7e6cd4f974..0fc838e0b8 100644 --- a/libraries/chain/include/steemit/chain/steem_object_types.hpp +++ b/libraries/chain/include/steemit/chain/steem_object_types.hpp @@ -41,6 +41,7 @@ enum object_type dynamic_global_property_object_type, account_object_type, account_authority_object_type, + account_bandwidth_object_type, witness_object_type, transaction_object_type, block_summary_object_type, @@ -69,6 +70,7 @@ enum object_type class dynamic_global_property_object; class account_object; class account_authority_object; +class account_bandwidth_object; class witness_object; class transaction_object; class block_summary_object; @@ -96,6 +98,7 @@ class block_stats_object; typedef oid< dynamic_global_property_object > dynamic_global_property_id_type; typedef oid< account_object > account_id_type; typedef oid< account_authority_object > account_authority_id_type; +typedef oid< account_bandwidth_object > account_bandwidth_id_type; typedef oid< witness_object > witness_id_type; typedef oid< transaction_object > transaction_object_id_type; typedef oid< block_summary_object > block_summary_id_type; @@ -120,6 +123,13 @@ typedef oid< savings_withdraw_object > savings_withdraw_id_type; typedef oid< decline_voting_rights_request_object > decline_voting_rights_request_id_type; typedef oid< block_stats_object > block_stats_id_type; +enum bandwidth_type +{ + post, ///< Rate limitting posting reward eligibility over time + forum, ///< Rate limitting for all forum related actions + market ///< Rate limitting for all other actions +}; + } } //steemit::chain namespace fc @@ -197,6 +207,7 @@ FC_REFLECT_ENUM( steemit::chain::object_type, (dynamic_global_property_object_type) (account_object_type) (account_authority_object_type) + (account_bandwidth_object_type) (witness_object_type) (transaction_object_type) (block_summary_object_type) @@ -224,3 +235,5 @@ FC_REFLECT_ENUM( steemit::chain::object_type, FC_REFLECT_TYPENAME( steemit::chain::shared_string ) FC_REFLECT_TYPENAME( steemit::chain::buffer_type ) + +FC_REFLECT_ENUM( steemit::chain::bandwidth_type, (post)(forum)(market) ) diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 57bbac7e0c..69bf0b4fa5 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -1953,7 +1953,9 @@ void reset_account_evaluator::do_apply( const reset_account_operation& op ) FC_ASSERT( false, "Reset Account Operation is currently disabled." ); const auto& acnt = _db.get_account( op.account_to_reset ); - FC_ASSERT( (_db.head_block_time() - acnt.last_bandwidth_update) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); + auto band = _db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( op.account_to_reset, bandwidth_type::forum ) ); + if( band != nullptr ) + FC_ASSERT( ( _db.head_block_time() - band->last_bandwidth_update ) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); FC_ASSERT( acnt.reset_account == op.reset_account, "Reset account does not match reset account on account." ); _db.update_owner_authority( acnt, op.new_owner_authority ); diff --git a/libraries/chainbase b/libraries/chainbase index 3f86a4c648..f1d4734e38 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 3f86a4c6483c8a07aec4b568bcd0a3708aca1c5f +Subproject commit f1d4734e3815dab157cb3329c76b3445ad966aec From 4fc01575882d094407d3322a591eae997c06e686 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 5 Dec 2016 14:24:19 -0500 Subject: [PATCH 49/77] Root post rate limiting now abstract resource type --- .../include/steemit/app/steem_api_objects.hpp | 4 +-- .../include/steemit/chain/account_object.hpp | 4 +-- libraries/chain/steem_evaluator.cpp | 35 +++++++++++++------ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/libraries/app/include/steemit/app/steem_api_objects.hpp b/libraries/app/include/steemit/app/steem_api_objects.hpp index eec44c5cd9..d10cec40f2 100644 --- a/libraries/app/include/steemit/app/steem_api_objects.hpp +++ b/libraries/app/include/steemit/app/steem_api_objects.hpp @@ -231,9 +231,7 @@ struct account_api_obj withdraw_routes( a.withdraw_routes ), proxied_vsf_votes( a.proxied_vsf_votes.size() ), witnesses_voted_for( a.witnesses_voted_for ), - last_post( a.last_post ), - last_root_post( a.last_root_post ), - post_bandwidth( a.post_bandwidth ) + last_post( a.last_post ) { size_t n = a.proxied_vsf_votes.size(); for( size_t i=0; i( boost::make_tuple( o.author, bandwidth_type::post ) ); + + if( band == nullptr ) + { + band = &_db.create< account_bandwidth_object >( [&]( account_bandwidth_object& b ) + { + b.account = o.author; + b.type = bandwidth_type::post; + }); + } + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) ) { if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) - FC_ASSERT( (now - auth.last_root_post) > STEEMIT_MIN_ROOT_COMMENT_INTERVAL, "You may only post once every 5 minutes.", ("now",now)("auth.last_root_post",auth.last_root_post) ); + FC_ASSERT( ( now - band->last_bandwidth_update ) > STEEMIT_MIN_ROOT_COMMENT_INTERVAL, "You may only post once every 5 minutes.", ("now",now)("last_root_post", band->last_bandwidth_update) ); else FC_ASSERT( (now - auth.last_post) > STEEMIT_MIN_REPLY_INTERVAL, "You may only comment once every 20 seconds.", ("now",now)("auth.last_post",auth.last_post) ); } @@ -394,22 +405,24 @@ void comment_evaluator::do_apply( const comment_operation& o ) } uint16_t reward_weight = STEEMIT_100_PERCENT; - uint64_t post_bandwidth = auth.post_bandwidth; + auto post_bandwidth = band->average_bandwidth; if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) && o.parent_author == STEEMIT_ROOT_POST_PARENT ) { - uint64_t post_delta_time = std::min( _db.head_block_time().sec_since_epoch() - auth.last_root_post.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); - uint32_t old_weight = uint32_t( ( post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - post_delta_time ) ) / STEEMIT_POST_AVERAGE_WINDOW ); + auto post_delta_time = std::min( now.sec_since_epoch() - band->last_bandwidth_update.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); + auto old_weight = ( post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - post_delta_time ) ) / STEEMIT_POST_AVERAGE_WINDOW; post_bandwidth = ( old_weight + STEEMIT_100_PERCENT ); - reward_weight = uint16_t( std::min( ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( post_bandwidth * post_bandwidth ), uint64_t( STEEMIT_100_PERCENT ) ) ); - } + reward_weight = uint16_t( std::min( ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( post_bandwidth.value * post_bandwidth.value ), uint64_t( STEEMIT_100_PERCENT ) ) ); - _db.modify( auth, [&]( account_object& a ) { - if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) + _db.modify( *band, [&]( account_bandwidth_object& b ) { - a.last_root_post = now; - a.post_bandwidth = uint32_t( post_bandwidth ); - } + b.last_bandwidth_update = now; + b.average_bandwidth = post_bandwidth; + }); + } + + db().modify( auth, [&]( account_object& a ) + { a.last_post = now; a.post_count++; }); From 559442c3c9966e13c9c19af67ceb454ee835bb66 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Wed, 14 Dec 2016 11:42:12 -0500 Subject: [PATCH 50/77] Update tests and deprecate current bandwidth algorithm --- libraries/chain/database.cpp | 11 ++++++++--- .../chain/include/steemit/chain/database.hpp | 7 ++++++- .../include/steemit/chain/steem_object_types.hpp | 6 +++--- libraries/chain/steem_evaluator.cpp | 4 ++-- tests/tests/operation_tests.cpp | 4 ++-- tests/tests/operation_time_tests.cpp | 15 ++++++++++----- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 712041e4f3..a59f9a8ac5 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -448,7 +448,7 @@ void database::pay_fee( const account_object& account, asset fee ) adjust_supply( -fee ); } -void database::update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ) +void database::old_update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ) { try { const auto& props = get_dynamic_global_properties(); if( props.total_vesting_shares.amount > 0 ) @@ -506,6 +506,11 @@ void database::update_account_bandwidth( const account_object& a, uint32_t trx_s } } FC_CAPTURE_AND_RETHROW() } +share_type database::update_account_bandwidth( const account_name_type& account, uint32_t trx_size, const bandwidth_type type ) +{ + return 0; +} + uint32_t database::witness_participation_rate()const { const dynamic_global_property_object& dpo = get_dynamic_global_properties(); @@ -3199,11 +3204,11 @@ void database::_apply_transaction(const signed_transaction& trx) for( const auto& auth : required ) { const auto& acnt = get_account(auth); - update_account_bandwidth( acnt, trx_size, bandwidth_type::forum ); + old_update_account_bandwidth( acnt, trx_size, bandwidth_type::old_forum ); for( const auto& op : trx.operations ) { if( is_market_operation( op ) ) { - update_account_bandwidth( acnt, trx_size, bandwidth_type::market ); + old_update_account_bandwidth( acnt, trx_size, bandwidth_type::old_market ); break; } } diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index f4fef10e66..48751fe651 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -146,7 +146,12 @@ namespace steemit { namespace chain { * Deducts fee from the account and the share supply */ void pay_fee( const account_object& a, asset fee ); - void update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ); + void old_update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ); + + /** + * Update an account's bandwidth and returns the new average bandwidth + */ + share_type update_account_bandwidth( const account_name_type& account, uint32_t trx_size, const bandwidth_type type ); void max_bandwidth_per_share()const; diff --git a/libraries/chain/include/steemit/chain/steem_object_types.hpp b/libraries/chain/include/steemit/chain/steem_object_types.hpp index 0fc838e0b8..7a6ef8638d 100644 --- a/libraries/chain/include/steemit/chain/steem_object_types.hpp +++ b/libraries/chain/include/steemit/chain/steem_object_types.hpp @@ -126,8 +126,8 @@ typedef oid< block_stats_object > block_stats_id_type; enum bandwidth_type { post, ///< Rate limitting posting reward eligibility over time - forum, ///< Rate limitting for all forum related actions - market ///< Rate limitting for all other actions + old_forum, ///< Rate limitting for all forum related actions + old_market ///< Rate limitting for all other actions }; } } //steemit::chain @@ -236,4 +236,4 @@ FC_REFLECT_ENUM( steemit::chain::object_type, FC_REFLECT_TYPENAME( steemit::chain::shared_string ) FC_REFLECT_TYPENAME( steemit::chain::buffer_type ) -FC_REFLECT_ENUM( steemit::chain::bandwidth_type, (post)(forum)(market) ) +FC_REFLECT_ENUM( steemit::chain::bandwidth_type, (post)(old_forum)(old_market) ) diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 2bc302d1d4..68d010deb6 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -1966,9 +1966,9 @@ void reset_account_evaluator::do_apply( const reset_account_operation& op ) FC_ASSERT( false, "Reset Account Operation is currently disabled." ); const auto& acnt = _db.get_account( op.account_to_reset ); - auto band = _db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( op.account_to_reset, bandwidth_type::forum ) ); + auto band = _db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( op.account_to_reset, bandwidth_type::old_forum ) ); if( band != nullptr ) - FC_ASSERT( ( _db.head_block_time() - band->last_bandwidth_update ) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); + FC_ASSERT( ( _db.head_block_time() - band->last_bandwidth_update ) > fc::days(60), "Account must be inactive for 60 days to be eligible for reset" ); FC_ASSERT( acnt.reset_account == op.reset_account, "Reset account does not match reset account on account." ); _db.update_owner_authority( acnt, op.new_owner_authority ); diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 5ac4f7d9e0..0f4773d83f 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -5904,7 +5904,6 @@ BOOST_AUTO_TEST_CASE( account_bandwidth ) generate_block(); db.skip_transaction_delta_check = false; - BOOST_REQUIRE( db.get_account( "alice" ).last_bandwidth_update != db.head_block_time() ); signed_transaction tx; transfer_operation op; @@ -5919,7 +5918,8 @@ BOOST_AUTO_TEST_CASE( account_bandwidth ) db.push_transaction( tx, 0 ); - BOOST_REQUIRE( db.get_account( "alice" ).last_market_bandwidth_update == db.head_block_time() ); + auto last_bandwidth_update = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::old_market ) ).last_bandwidth_update; + BOOST_REQUIRE( last_bandwidth_update == db.head_block_time() ); op.amount = ASSET( "0.100 TESTS" ); tx.clear(); diff --git a/tests/tests/operation_time_tests.cpp b/tests/tests/operation_time_tests.cpp index d54bf62c6a..efc6f6d1b0 100644 --- a/tests/tests/operation_time_tests.cpp +++ b/tests/tests/operation_time_tests.cpp @@ -2203,8 +2203,9 @@ BOOST_AUTO_TEST_CASE( post_rate_limit ) db.push_transaction( tx, 0 ); uint64_t alice_post_bandwidth = STEEMIT_100_PERCENT; + auto bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::post ) ).average_bandwidth; - BOOST_REQUIRE( alice.post_bandwidth == alice_post_bandwidth ); + BOOST_REQUIRE( bandwidth == alice_post_bandwidth ); BOOST_REQUIRE( db.get_comment( "alice", string( "test1" ) ).reward_weight == STEEMIT_100_PERCENT ); tx.operations.clear(); @@ -2219,8 +2220,9 @@ BOOST_AUTO_TEST_CASE( post_rate_limit ) db.push_transaction( tx, 0 ); alice_post_bandwidth = STEEMIT_100_PERCENT + ( alice_post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - STEEMIT_MIN_ROOT_COMMENT_INTERVAL.to_seconds() - STEEMIT_BLOCK_INTERVAL ) / STEEMIT_POST_AVERAGE_WINDOW ); + bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::post ) ).average_bandwidth; - BOOST_REQUIRE( db.get_account( "alice" ).post_bandwidth == alice_post_bandwidth ); + BOOST_REQUIRE( bandwidth == alice_post_bandwidth ); BOOST_REQUIRE( db.get_comment( "alice", string( "test2" ) ).reward_weight == STEEMIT_100_PERCENT ); generate_blocks( db.head_block_time() + STEEMIT_MIN_ROOT_COMMENT_INTERVAL + fc::seconds( STEEMIT_BLOCK_INTERVAL ), true ); @@ -2235,8 +2237,9 @@ BOOST_AUTO_TEST_CASE( post_rate_limit ) db.push_transaction( tx, 0 ); alice_post_bandwidth = STEEMIT_100_PERCENT + ( alice_post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - STEEMIT_MIN_ROOT_COMMENT_INTERVAL.to_seconds() - STEEMIT_BLOCK_INTERVAL ) / STEEMIT_POST_AVERAGE_WINDOW ); + bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::post ) ).average_bandwidth; - BOOST_REQUIRE( db.get_account( "alice" ).post_bandwidth == alice_post_bandwidth ); + BOOST_REQUIRE( bandwidth == alice_post_bandwidth ); BOOST_REQUIRE( db.get_comment( "alice", string( "test3" ) ).reward_weight == STEEMIT_100_PERCENT ); generate_blocks( db.head_block_time() + STEEMIT_MIN_ROOT_COMMENT_INTERVAL + fc::seconds( STEEMIT_BLOCK_INTERVAL ), true ); @@ -2251,8 +2254,9 @@ BOOST_AUTO_TEST_CASE( post_rate_limit ) db.push_transaction( tx, 0 ); alice_post_bandwidth = STEEMIT_100_PERCENT + ( alice_post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - STEEMIT_MIN_ROOT_COMMENT_INTERVAL.to_seconds() - STEEMIT_BLOCK_INTERVAL ) / STEEMIT_POST_AVERAGE_WINDOW ); + bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::post ) ).average_bandwidth; - BOOST_REQUIRE( db.get_account( "alice" ).post_bandwidth == alice_post_bandwidth ); + BOOST_REQUIRE( bandwidth == alice_post_bandwidth ); BOOST_REQUIRE( db.get_comment( "alice", string( "test4" ) ).reward_weight == STEEMIT_100_PERCENT ); generate_blocks( db.head_block_time() + STEEMIT_MIN_ROOT_COMMENT_INTERVAL + fc::seconds( STEEMIT_BLOCK_INTERVAL ), true ); @@ -2268,8 +2272,9 @@ BOOST_AUTO_TEST_CASE( post_rate_limit ) alice_post_bandwidth = STEEMIT_100_PERCENT + ( alice_post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - STEEMIT_MIN_ROOT_COMMENT_INTERVAL.to_seconds() - STEEMIT_BLOCK_INTERVAL ) / STEEMIT_POST_AVERAGE_WINDOW ); auto reward_weight = ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( alice_post_bandwidth * alice_post_bandwidth ); + bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::post ) ).average_bandwidth; - BOOST_REQUIRE( db.get_account( "alice" ).post_bandwidth == alice_post_bandwidth ); + BOOST_REQUIRE( bandwidth == alice_post_bandwidth ); BOOST_REQUIRE( db.get_comment( "alice", string( "test5" ) ).reward_weight == reward_weight ); } FC_LOG_AND_RETHROW() From a23e51a7cc9c39852a0e14894606580360f25996 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Wed, 14 Dec 2016 16:16:24 -0500 Subject: [PATCH 51/77] Implement new bandwidth algorithm #563 --- libraries/app/database_api.cpp | 18 ++++-- .../app/include/steemit/app/database_api.hpp | 3 + libraries/app/include/steemit/app/state.hpp | 2 +- .../include/steemit/app/steem_api_objects.hpp | 59 ++++++++++++++--- libraries/chain/database.cpp | 63 ++++++++++++++++--- .../include/steemit/chain/account_object.hpp | 2 + .../chain/include/steemit/chain/database.hpp | 4 +- .../steemit/chain/steem_object_types.hpp | 10 +-- tests/tests/operation_tests.cpp | 12 +++- 9 files changed, 143 insertions(+), 30 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index d4017fb108..6df827b633 100755 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -382,7 +382,7 @@ vector< extended_account > database_api_impl::get_accounts( vector< string > nam auto itr = idx.find( name ); if ( itr != idx.end() ) { - results.push_back( extended_account( *itr, _db.get< account_authority_object, by_account >( itr->name ) ) ); + results.push_back( extended_account( *itr, _db ) ); if( _follow_api ) { @@ -444,7 +444,7 @@ vector> database_api_impl::lookup_account_names(const if( itr ) { - result.push_back( account_api_obj( *itr, _db.get< account_authority_object, by_account >( name ) ) ); + result.push_back( account_api_obj( *itr, _db ) ); } else { @@ -593,6 +593,16 @@ vector< withdraw_route > database_api::get_withdraw_routes( string account, with }); } +optional< account_bandwidth_api_obj > database_api::get_account_bandwidth( string account, bandwidth_type type )const +{ + optional< account_bandwidth_api_obj > result; + auto band = my->_db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( account, type ) ); + if( band != nullptr ) + result = *band; + + return result; +} + ////////////////////////////////////////////////////////////////////// // // // Witnesses // @@ -1863,7 +1873,7 @@ state database_api::get_state( string path )const if( part[0].size() && part[0][0] == '@' ) { auto acnt = part[0].substr(1); - _state.accounts[acnt] = extended_account( my->_db.get_account(acnt), my->_db.get< account_authority_object, by_account >(acnt) ); + _state.accounts[acnt] = extended_account( my->_db.get_account(acnt), my->_db ); if( my->_follow_api ) { _state.accounts[acnt].reputation = my->_follow_api->get_account_reputations( acnt, 1 )[0].reputation; @@ -2177,7 +2187,7 @@ state database_api::get_state( string path )const for( const auto& a : accounts ) { _state.accounts.erase(""); - _state.accounts[a] = extended_account( my->_db.get_account( a ), my->_db.get< account_authority_object, by_account >( a ) ); + _state.accounts[a] = extended_account( my->_db.get_account( a ), my->_db ); if( my->_follow_api ) { _state.accounts[a].reputation = my->_follow_api->get_account_reputations( a, 1 )[0].reputation; diff --git a/libraries/app/include/steemit/app/database_api.hpp b/libraries/app/include/steemit/app/database_api.hpp index b87dee1a74..dd30810473 100755 --- a/libraries/app/include/steemit/app/database_api.hpp +++ b/libraries/app/include/steemit/app/database_api.hpp @@ -226,6 +226,8 @@ class database_api vector< withdraw_route > get_withdraw_routes( string account, withdraw_route_type type = outgoing )const; + optional< account_bandwidth_api_obj > get_account_bandwidth( string account, bandwidth_type type )const; + vector< savings_withdraw_api_obj > get_savings_withdraw_from( string account )const; vector< savings_withdraw_api_obj > get_savings_withdraw_to( string account )const; @@ -493,6 +495,7 @@ FC_API(steemit::app::database_api, (get_recovery_request) (get_escrow) (get_withdraw_routes) + (get_account_bandwidth) (get_savings_withdraw_from) (get_savings_withdraw_to) diff --git a/libraries/app/include/steemit/app/state.hpp b/libraries/app/include/steemit/app/state.hpp index 328b1ec78a..af7fc2ff0c 100644 --- a/libraries/app/include/steemit/app/state.hpp +++ b/libraries/app/include/steemit/app/state.hpp @@ -89,7 +89,7 @@ namespace steemit { namespace app { struct extended_account : public account_api_obj { extended_account(){} - extended_account( const account_object& a, const account_authority_object& auth ):account_api_obj( a, auth ){} + extended_account( const account_object& a, const database& db ):account_api_obj( a, db ){} asset vesting_balance; /// convert vesting_shares to vesting steem share_type reputation = 0; diff --git a/libraries/app/include/steemit/app/steem_api_objects.hpp b/libraries/app/include/steemit/app/steem_api_objects.hpp index d10cec40f2..72aa5f8bd7 100644 --- a/libraries/app/include/steemit/app/steem_api_objects.hpp +++ b/libraries/app/include/steemit/app/steem_api_objects.hpp @@ -49,6 +49,7 @@ typedef chain::withdraw_vesting_route_object withdraw_vesting_route_ap typedef chain::decline_voting_rights_request_object decline_voting_rights_request_api_obj; typedef chain::witness_vote_object witness_vote_api_obj; typedef chain::witness_schedule_object witness_schedule_api_obj; +typedef chain::account_bandwidth_object account_bandwidth_api_obj; struct comment_api_obj { @@ -184,16 +185,12 @@ struct tag_api_obj struct account_api_obj { - account_api_obj( const chain::account_object& a, const chain::account_authority_object& auth ) : + account_api_obj( const chain::account_object& a, const chain::database& db ) : id( a.id ), name( a.name ), - owner( authority( auth.owner ) ), - active( authority( auth.active ) ), - posting( authority( auth.posting ) ), memo_key( a.memo_key ), json_metadata( to_string( a.json_metadata ) ), proxy( a.proxy ), - last_owner_update( auth.last_owner_update ), last_account_update( a.last_account_update ), created( a.created ), mined( a.mined ), @@ -236,6 +233,46 @@ struct account_api_obj size_t n = a.proxied_vsf_votes.size(); for( size_t i=0; i( name ); + owner = authority( auth.owner ); + active = authority( auth.active ); + posting = authority( auth.posting ); + last_owner_update = auth.last_owner_update; + + auto old_forum = db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( name, bandwidth_type::old_forum ) ); + if( old_forum != nullptr ) + { + average_bandwidth = old_forum->average_bandwidth; + lifetime_bandwidth = old_forum->lifetime_bandwidth; + last_bandwidth_update = old_forum->last_bandwidth_update; + } + + auto old_market = db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( name, bandwidth_type::old_market ) ); + if( old_market != nullptr ) + { + average_market_bandwidth = old_market->average_bandwidth; + last_market_bandwidth_update = old_market->last_bandwidth_update; + } + + auto post = db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( name, bandwidth_type::post ) ); + if( post != nullptr ) + { + last_root_post = post->last_bandwidth_update; + post_bandwidth = post->average_bandwidth; + } + + auto forum = db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( name, bandwidth_type::forum ) ); + if( forum != nullptr ) + { + new_average_bandwidth = forum->average_bandwidth; + } + + auto market = db.find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( name, bandwidth_type::market ) ); + if( market != nullptr ) + { + new_average_market_bandwidth = market->average_bandwidth; + } } @@ -300,15 +337,18 @@ struct account_api_obj uint16_t witnesses_voted_for; - uint64_t average_bandwidth; - uint64_t lifetime_bandwidth; + share_type average_bandwidth = 0; + share_type lifetime_bandwidth = 0; time_point_sec last_bandwidth_update; - uint64_t average_market_bandwidth; + share_type average_market_bandwidth = 0; time_point_sec last_market_bandwidth_update; time_point_sec last_post; time_point_sec last_root_post; - uint32_t post_bandwidth; + share_type post_bandwidth = STEEMIT_100_PERCENT; + + share_type new_average_bandwidth; + share_type new_average_market_bandwidth; }; struct owner_authority_history_api_obj @@ -471,6 +511,7 @@ FC_REFLECT( steemit::app::account_api_obj, (average_bandwidth)(lifetime_bandwidth)(last_bandwidth_update) (average_market_bandwidth)(last_market_bandwidth_update) (last_post)(last_root_post)(post_bandwidth) + (new_average_bandwidth)(new_average_market_bandwidth) ) FC_REFLECT( steemit::app::owner_authority_history_api_obj, diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index a59f9a8ac5..5905228ff5 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -465,12 +465,6 @@ void database::old_update_account_bandwidth( const account_object& a, uint32_t t b.type = type; }); } -#ifdef IS_TEST_NET - if( !skip_transaction_delta_check ) -#endif - // Soft fork to prevent multiple transactions for an account in the same block - FC_ASSERT( !is_producing() || band->last_bandwidth_update < head_block_time(), - "Account already transacted this block." ); modify( *band, [&]( account_bandwidth_object& b ) { @@ -506,9 +500,60 @@ void database::old_update_account_bandwidth( const account_object& a, uint32_t t } } FC_CAPTURE_AND_RETHROW() } -share_type database::update_account_bandwidth( const account_name_type& account, uint32_t trx_size, const bandwidth_type type ) +bool database::update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ) { - return 0; + const auto& props = get_dynamic_global_properties(); + bool has_bandwidth = true; + + if( props.total_vesting_shares.amount > 0 ) + { + auto band = find< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( a.name, type ) ); + + if( band == nullptr ) + { + band = &create< account_bandwidth_object >( [&]( account_bandwidth_object& b ) + { + b.account = a.name; + b.type = type; + }); + } + + share_type new_bandwidth; + share_type trx_bandwidth = trx_size * STEEMIT_BANDWIDTH_PRECISION; + auto delta_time = ( head_block_time() - band->last_bandwidth_update ).to_seconds(); + + if( delta_time > STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS ) + new_bandwidth = 0; + else + new_bandwidth = ( ( ( STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS - delta_time ) * fc::uint128( band->average_bandwidth.value ) ) + / STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS ).to_uint64(); + + new_bandwidth += trx_bandwidth; + + modify( *band, [&]( account_bandwidth_object& b ) + { + b.average_bandwidth = new_bandwidth; + b.lifetime_bandwidth += trx_bandwidth; + b.last_bandwidth_update = head_block_time(); + }); + + fc::uint128 account_vshares( a.vesting_shares.amount.value ); + fc::uint128 total_vshares( props.total_vesting_shares.amount.value ); + fc::uint128 account_average_bandwidth( band->average_bandwidth.value ); + fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth ); + + has_bandwidth = ( account_vshares * max_virtual_bandwidth ) > ( account_average_bandwidth * total_vshares ); + + if( is_producing() ) + FC_ASSERT( has_bandwidth, + "Account exceeded maximum allowed bandwidth per vesting share.", + ("account_vshares", account_vshares) + ("account_average_bandwidth", account_average_bandwidth) + ("max_virtual_bandwidth", max_virtual_bandwidth) + ("total_vesting_shares", total_vshares) ); + } + + return has_bandwidth; } uint32_t database::witness_participation_rate()const @@ -3205,10 +3250,12 @@ void database::_apply_transaction(const signed_transaction& trx) const auto& acnt = get_account(auth); old_update_account_bandwidth( acnt, trx_size, bandwidth_type::old_forum ); + update_account_bandwidth( acnt, trx_size, bandwidth_type::forum ); for( const auto& op : trx.operations ) { if( is_market_operation( op ) ) { old_update_account_bandwidth( acnt, trx_size, bandwidth_type::old_market ); + update_account_bandwidth( acnt, trx_size * 10, bandwidth_type::market ); break; } } diff --git a/libraries/chain/include/steemit/chain/account_object.hpp b/libraries/chain/include/steemit/chain/account_object.hpp index b4bf62006d..baa8fe5d08 100644 --- a/libraries/chain/include/steemit/chain/account_object.hpp +++ b/libraries/chain/include/steemit/chain/account_object.hpp @@ -142,6 +142,8 @@ namespace steemit { namespace chain { c( *this ); } + account_bandwidth_object() {} + id_type id; account_name_type account; diff --git a/libraries/chain/include/steemit/chain/database.hpp b/libraries/chain/include/steemit/chain/database.hpp index 48751fe651..2c40cd444b 100644 --- a/libraries/chain/include/steemit/chain/database.hpp +++ b/libraries/chain/include/steemit/chain/database.hpp @@ -149,9 +149,9 @@ namespace steemit { namespace chain { void old_update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ); /** - * Update an account's bandwidth and returns the new average bandwidth + * Update an account's bandwidth and returns if the account had the requisite bandwidth for the trx */ - share_type update_account_bandwidth( const account_name_type& account, uint32_t trx_size, const bandwidth_type type ); + bool update_account_bandwidth( const account_object& a, uint32_t trx_size, const bandwidth_type type ); void max_bandwidth_per_share()const; diff --git a/libraries/chain/include/steemit/chain/steem_object_types.hpp b/libraries/chain/include/steemit/chain/steem_object_types.hpp index 7a6ef8638d..de5d52be52 100644 --- a/libraries/chain/include/steemit/chain/steem_object_types.hpp +++ b/libraries/chain/include/steemit/chain/steem_object_types.hpp @@ -125,9 +125,11 @@ typedef oid< block_stats_object > block_stats_id_type; enum bandwidth_type { - post, ///< Rate limitting posting reward eligibility over time - old_forum, ///< Rate limitting for all forum related actions - old_market ///< Rate limitting for all other actions + post, ///< Rate limiting posting reward eligibility over time + forum, ///< Rate limiting for all forum related actins + market, ///< Rate limiting for all other actions + old_forum, ///< Rate limiting for all forum related actions (deprecated) + old_market ///< Rate limiting for all other actions (deprecated) }; } } //steemit::chain @@ -236,4 +238,4 @@ FC_REFLECT_ENUM( steemit::chain::object_type, FC_REFLECT_TYPENAME( steemit::chain::shared_string ) FC_REFLECT_TYPENAME( steemit::chain::buffer_type ) -FC_REFLECT_ENUM( steemit::chain::bandwidth_type, (post)(old_forum)(old_market) ) +FC_REFLECT_ENUM( steemit::chain::bandwidth_type, (post)(forum)(market)(old_forum)(old_market) ) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 0f4773d83f..cdb7a648f1 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -5918,8 +5918,11 @@ BOOST_AUTO_TEST_CASE( account_bandwidth ) db.push_transaction( tx, 0 ); - auto last_bandwidth_update = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::old_market ) ).last_bandwidth_update; + auto last_bandwidth_update = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::market ) ).last_bandwidth_update; + auto average_bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::market ) ).average_bandwidth; BOOST_REQUIRE( last_bandwidth_update == db.head_block_time() ); + BOOST_REQUIRE( average_bandwidth == fc::raw::pack_size( tx ) * 10 * STEEMIT_BANDWIDTH_PRECISION ); + auto total_bandwidth = average_bandwidth; op.amount = ASSET( "0.100 TESTS" ); tx.clear(); @@ -5927,7 +5930,12 @@ BOOST_AUTO_TEST_CASE( account_bandwidth ) tx.set_expiration( db.head_block_time() + STEEMIT_MAX_TIME_UNTIL_EXPIRATION ); tx.sign( alice_private_key, db.get_chain_id() ); - STEEMIT_REQUIRE_THROW( db.push_transaction( tx, 0 ), fc::assert_exception ); + db.push_transaction( tx, 0 ); + + last_bandwidth_update = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::market ) ).last_bandwidth_update; + average_bandwidth = db.get< account_bandwidth_object, by_account_bandwidth_type >( boost::make_tuple( "alice", bandwidth_type::market ) ).average_bandwidth; + BOOST_REQUIRE( last_bandwidth_update == db.head_block_time() ); + BOOST_REQUIRE( average_bandwidth == total_bandwidth + fc::raw::pack_size( tx ) * 10 * STEEMIT_BANDWIDTH_PRECISION ); } FC_LOG_AND_RETHROW() } From 52ac1f07c1d1a2db39439d81d37c3f694c6caa41 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 20 Dec 2016 11:12:28 -0500 Subject: [PATCH 52/77] Refactor pow2 required authorities to use visitor #726 --- .../steemit/protocol/steem_operations.hpp | 18 +------------ libraries/protocol/steem_operations.cpp | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/libraries/protocol/include/steemit/protocol/steem_operations.hpp b/libraries/protocol/include/steemit/protocol/steem_operations.hpp index f22bdd6a83..8e6c6c0254 100644 --- a/libraries/protocol/include/steemit/protocol/steem_operations.hpp +++ b/libraries/protocol/include/steemit/protocol/steem_operations.hpp @@ -614,23 +614,7 @@ namespace steemit { namespace protocol { void validate()const; - void get_required_active_authorities( flat_set& a )const - { - if( !new_owner_key ) - { - switch( work.which() ) - { - case pow2_work::tag< pow2 >::value: - a.insert( work.get< pow2 >().input.worker_account ); - break; - case pow2_work::tag< equihash_pow >::value: - a.insert( work.get< equihash_pow >().input.worker_account ); - break; - default: - break; - } - } - } + void get_required_active_authorities( flat_set& a )const; void get_required_authorities( vector< authority >& a )const { diff --git a/libraries/protocol/steem_operations.cpp b/libraries/protocol/steem_operations.cpp index 5d00f73c5e..6fd84e3512 100644 --- a/libraries/protocol/steem_operations.cpp +++ b/libraries/protocol/steem_operations.cpp @@ -216,6 +216,31 @@ namespace steemit { namespace protocol { work.visit( pow2_operation_validate_visitor() ); } + struct pow2_operation_get_required_active_visitor + { + typedef void result_type; + + pow2_operation_get_required_active_visitor( flat_set< account_name_type >& required_active ) + : _required_active( required_active ) {} + + template< typename PowType > + void operator()( const PowType& work )const + { + _required_active.insert( work.input.worker_account ); + } + + flat_set& _required_active; + }; + + void pow2_operation::get_required_active_authorities( flat_set& a )const + { + if( !new_owner_key ) + { + pow2_operation_get_required_active_visitor vtor( a ); + work.visit( vtor ); + } + } + void pow::create( const fc::ecc::private_key& w, const digest_type& i ) { input = i; From 23609e6473ef8fc8af692ca0861a7ba882a79947 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Wed, 21 Dec 2016 11:50:51 -0500 Subject: [PATCH 53/77] Simplify logging #710 --- libraries/chain/database.cpp | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 6a474067b8..6e0c164ba3 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -4026,18 +4026,12 @@ void database::set_hardfork( uint32_t hardfork, bool apply_now ) void database::apply_hardfork( uint32_t hardfork ) { - auto log_hardfork = [this]( int hf ) - { - if( _log_hardforks ) - { - elog( "HARDFORK ${hf} at block ${b}", ("hf", hf)("b", head_block_num()) ); - } - }; + if( _log_hardforks ) + elog( "HARDFORK ${hf} at block ${b}", ("hf", hardfork)("b", head_block_num()) ); switch( hardfork ) { case STEEMIT_HARDFORK_0_1: - log_hardfork(1); perform_vesting_share_split( 1000000 ); #ifdef IS_TEST_NET { @@ -4054,34 +4048,26 @@ void database::apply_hardfork( uint32_t hardfork ) #endif break; case STEEMIT_HARDFORK_0_2: - log_hardfork(2); retally_witness_votes(); break; case STEEMIT_HARDFORK_0_3: - log_hardfork(3); retally_witness_votes(); break; case STEEMIT_HARDFORK_0_4: - log_hardfork(4); reset_virtual_schedule_time(); break; case STEEMIT_HARDFORK_0_5: - log_hardfork(5); break; case STEEMIT_HARDFORK_0_6: - log_hardfork(6); retally_witness_vote_counts(); retally_comment_children(); break; case STEEMIT_HARDFORK_0_7: - log_hardfork(7); break; case STEEMIT_HARDFORK_0_8: - log_hardfork(8); retally_witness_vote_counts(true); break; case STEEMIT_HARDFORK_0_9: - log_hardfork(9); { for( const std::string& acc : hardfork9::get_compromised_accounts() ) { @@ -4100,14 +4086,11 @@ void database::apply_hardfork( uint32_t hardfork ) } break; case STEEMIT_HARDFORK_0_10: - log_hardfork(10); retally_liquidity_weight(); break; case STEEMIT_HARDFORK_0_11: - log_hardfork(11); break; case STEEMIT_HARDFORK_0_12: - log_hardfork(12); { const auto& comment_idx = get_index< comment_index >().indices(); @@ -4159,16 +4142,12 @@ void database::apply_hardfork( uint32_t hardfork ) } break; case STEEMIT_HARDFORK_0_13: - log_hardfork(13); break; case STEEMIT_HARDFORK_0_14: - log_hardfork(14); break; case STEEMIT_HARDFORK_0_15: - log_hardfork(15); break; case STEEMIT_HARDFORK_0_16: - log_hardfork(16); modify( get_feed_history(), [&]( feed_history_object& fho ) { while( fho.price_history.size() > STEEMIT_FEED_HISTORY_WINDOW ) From 37f78ed324a0a081d7765b0e7abad0d8c15d7d91 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 23 Dec 2016 12:36:14 -0500 Subject: [PATCH 54/77] Implement tests for some illegal asset strings #102 --- libraries/protocol/asset.cpp | 8 ++++++-- tests/tests/serialization_tests.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/libraries/protocol/asset.cpp b/libraries/protocol/asset.cpp index 5d6492823c..c9e00b82aa 100644 --- a/libraries/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -68,9 +68,13 @@ namespace steemit { namespace protocol { result.amount.value -= result.precision(); } auto symbol = s.substr( space_pos + 1 ); + size_t symbol_size = symbol.size(); - if( symbol.size() ) - memcpy( sy+1, symbol.c_str(), std::min(symbol.size(),size_t(6)) ); + if( symbol_size > 0 ) + { + FC_ASSERT( symbol_size <= 6 ); + memcpy( sy+1, symbol.c_str(), symbol_size ); + } return result; } diff --git a/tests/tests/serialization_tests.cpp b/tests/tests/serialization_tests.cpp index 8c9ef58a7e..bd15217086 100644 --- a/tests/tests/serialization_tests.cpp +++ b/tests/tests/serialization_tests.cpp @@ -141,6 +141,35 @@ BOOST_AUTO_TEST_CASE( asset_test ) BOOST_CHECK_EQUAL( sbd.symbol, SBD_SYMBOL); BOOST_CHECK_EQUAL( asset(50, SBD_SYMBOL).to_string(), "0.050 TBD" ); BOOST_CHECK_EQUAL( asset(50000, SBD_SYMBOL).to_string(), "50.000 TBD" ); + + BOOST_CHECK_THROW( steem.set_decimals(100), fc::exception ); + char* steem_sy = (char*) &steem.symbol; + steem_sy[0] = 100; + BOOST_CHECK_THROW( steem.decimals(), fc::exception ); + steem_sy[6] = 'A'; + steem_sy[7] = 'A'; + + auto check_sym = []( const asset& a ) -> std::string + { + auto symbol = a.symbol_name(); + wlog( "symbol_name is ${s}", ("s", symbol) ); + return symbol; + }; + + BOOST_CHECK_THROW( check_sym(steem), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.00000000000000000000 TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.000TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1. 333 TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1 .333 TESTS" ), fc::exception ); + asset unusual = asset::from_string( "1. 333 X" ); + FC_ASSERT( unusual.decimals() == 0 ); + FC_ASSERT( unusual.symbol_name() == "333 X" ); + BOOST_CHECK_THROW( asset::from_string( "1 .333 X" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1 .333" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1 1.1" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "11111111111111111111111111111111111111111111111 TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.1.1 TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.abc TESTS" ), fc::exception ); } FC_LOG_AND_RETHROW() } From d807d13e5b908dca9f77e972ef3aad8d5c3baab7 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 23 Dec 2016 11:02:53 -0500 Subject: [PATCH 55/77] Fix handling of illegal values in asset strings #102 --- libraries/protocol/asset.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/libraries/protocol/asset.cpp b/libraries/protocol/asset.cpp index c9e00b82aa..ab20cc581c 100644 --- a/libraries/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -16,12 +16,12 @@ namespace steemit { namespace protocol { std::string asset::symbol_name()const { auto a = (const char*)&symbol; - assert( a[7] == 0 ); + FC_ASSERT( a[7] == 0 ); return &a[1]; } - int64_t asset::precision()const { - + int64_t asset::precision()const + { static int64_t table[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000ll, @@ -29,15 +29,21 @@ namespace steemit { namespace protocol { 100000000000ll, 1000000000000ll, 10000000000000ll, 100000000000000ll }; - return table[ decimals() ]; + uint8_t d = decimals(); + FC_ASSERT( d < 15 ); + return table[ d ]; } - string asset::to_string()const { - string result = fc::to_string(amount.value / precision()); + string asset::to_string()const + { + int64_t prec = precision(); + string result = fc::to_string(amount.value / prec); if( decimals() ) { - auto fract = amount.value % precision(); - result += "." + fc::to_string(precision() + fract).erase(0,1); + auto fract = amount.value % prec; + result += "." + fc::to_string(prec + fract).erase(0,1); + wlog( "prec is ${prec} fract is ${fract} p+f is ${pf} result is ${result}", + ("prec", prec)("fract", fract)("result", result)("pf", prec+fract) ); } return result + " " + symbol_name(); } @@ -50,16 +56,19 @@ namespace steemit { namespace protocol { auto space_pos = s.find( " " ); auto dot_pos = s.find( "." ); + FC_ASSERT( space_pos != std::string::npos ); + asset result; result.symbol = uint64_t(0); auto sy = (char*)&result.symbol; - *sy = (char) dot_pos; // Mask due to undefined architecture behavior auto intpart = s.substr( 0, dot_pos ); result.amount = fc::to_int64(intpart); std::string fractpart; if( dot_pos != std::string::npos ) { + FC_ASSERT( space_pos > dot_pos ); + auto fractpart = "1" + s.substr( dot_pos + 1, space_pos - dot_pos - 1 ); result.set_decimals( fractpart.size() - 1 ); @@ -67,6 +76,10 @@ namespace steemit { namespace protocol { result.amount.value += fc::to_int64(fractpart); result.amount.value -= result.precision(); } + else + { + result.set_decimals( 0 ); + } auto symbol = s.substr( space_pos + 1 ); size_t symbol_size = symbol.size(); From cf93aaa935655ae42316f1954ee855dd139c3683 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 23 Dec 2016 12:23:06 -0500 Subject: [PATCH 56/77] Some more defensive FC_ASSERT() #102 --- libraries/protocol/asset.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/protocol/asset.cpp b/libraries/protocol/asset.cpp index ab20cc581c..a4a20eff49 100644 --- a/libraries/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -2,26 +2,43 @@ #include #include +/* + +The bounds on asset serialization are as follows: + +index : field +0 : decimals +1..6 : symbol + 7 : \0 +*/ + namespace steemit { namespace protocol { typedef boost::multiprecision::int128_t int128_t; - uint8_t asset::decimals()const { + uint8_t asset::decimals()const + { auto a = (const char*)&symbol; - return a[0]; + uint8_t result = uint8_t( a[0] ); + FC_ASSERT( result < 15 ); + return result; } - void asset::set_decimals(uint8_t d){ + + void asset::set_decimals(uint8_t d) + { + FC_ASSERT( d < 15 ); auto a = (char*)&symbol; a[0] = d; } - std::string asset::symbol_name()const { + std::string asset::symbol_name()const + { auto a = (const char*)&symbol; FC_ASSERT( a[7] == 0 ); return &a[1]; } - int64_t asset::precision()const - { + int64_t asset::precision()const + { static int64_t table[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000ll, @@ -30,7 +47,6 @@ namespace steemit { namespace protocol { 10000000000000ll, 100000000000000ll }; uint8_t d = decimals(); - FC_ASSERT( d < 15 ); return table[ d ]; } @@ -41,9 +57,11 @@ namespace steemit { namespace protocol { if( decimals() ) { auto fract = amount.value % prec; + // prec is a power of ten, so for example when working with + // 7.005 we have fract = 5, prec = 1000. So prec+fract=1005 + // has the correct number of zeros and we can simply trim the + // leading 1. result += "." + fc::to_string(prec + fract).erase(0,1); - wlog( "prec is ${prec} fract is ${fract} p+f is ${pf} result is ${result}", - ("prec", prec)("fract", fract)("result", result)("pf", prec+fract) ); } return result + " " + symbol_name(); } From b03fdf903e061bbb3dcd6f280ceafd4b6148a23a Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 23 Dec 2016 14:13:36 -0500 Subject: [PATCH 57/77] Use more efficient check for non-decimal assets #102 --- libraries/protocol/asset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/protocol/asset.cpp b/libraries/protocol/asset.cpp index a4a20eff49..d03325e6d7 100644 --- a/libraries/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -54,7 +54,7 @@ namespace steemit { namespace protocol { { int64_t prec = precision(); string result = fc::to_string(amount.value / prec); - if( decimals() ) + if( prec > 1 ) { auto fract = amount.value % prec; // prec is a power of ten, so for example when working with From 1dcc9b886cfe60e230f0c6d9fb63f3d985d158b5 Mon Sep 17 00:00:00 2001 From: JustinW Date: Mon, 2 Jan 2017 19:43:24 +0000 Subject: [PATCH 58/77] Fixed error in Dockerfile and added line in the buildscript to extract the created coverage.xml file into jenkins to be published --- Dockerfile | 1 - ciscripts/buildscript.sh | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ceabad4140..0b8ce58251 100644 --- a/Dockerfile +++ b/Dockerfile @@ -137,7 +137,6 @@ RUN \ python-dev \ python2.7-dev \ python3-dev \ - lcov \ && \ apt-get autoremove -y && \ rm -rf \ diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index 22f5f5c149..748d9c2c31 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -6,3 +6,4 @@ fi sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME +sudo docker run -it --rm -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins From 1ba05563a04cdba930656bc92a82a7c940be449f Mon Sep 17 00:00:00 2001 From: JustinW Date: Mon, 2 Jan 2017 20:27:48 +0000 Subject: [PATCH 59/77] Removed -it flag from docker command because it's not running in a terminal --- ciscripts/buildscript.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index 748d9c2c31..757a7b8056 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -6,4 +6,4 @@ fi sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME -sudo docker run -it --rm -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins +sudo docker run --rm -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins From d273dde176057c611ff60ba3b17835a1e1165fb7 Mon Sep 17 00:00:00 2001 From: JustinW Date: Mon, 2 Jan 2017 21:13:27 +0000 Subject: [PATCH 60/77] Docker doesn't like the --rm flag to remove the container upon run when not running it from a terminval, it'll already get removed in the buildsuccess script so just taking it out --- ciscripts/buildscript.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index 757a7b8056..f605bf054d 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -6,4 +6,4 @@ fi sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME -sudo docker run --rm -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins +sudo docker run -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins From 3365063a0045bb0c05cad61653bd068bc3f2c558 Mon Sep 17 00:00:00 2001 From: JustinW Date: Mon, 2 Jan 2017 22:10:22 +0000 Subject: [PATCH 61/77] cobertura plugin wants cobertura.xml in a path relative to the workspace --- ciscripts/buildscript.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index f605bf054d..3560706198 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -7,3 +7,4 @@ sudo docker build -t=$IMAGE_NAME . sudo docker login --username=$DOCKER_USER --password=$DOCKER_PASS sudo docker push $IMAGE_NAME sudo docker run -v /var/jenkins_home:/var/jenkins $IMAGE_NAME cp -r /var/cobertura /var/jenkins +cp -r /var/jenkins_home/cobertura . From 77ee89223054615c5376d4b02ca1514c8733d433 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 2 Jan 2017 17:32:49 -0500 Subject: [PATCH 62/77] Add extra assertions to detect a corrupt block log #738 #675 --- libraries/app/application.cpp | 6 +++--- libraries/chain/block_log.cpp | 30 ++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 4a965d6bbc..b260f1af24 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -523,9 +523,9 @@ namespace detail { bool is_included_block(const block_id_type& block_id) { - uint32_t block_num = block_header::num_from_id(block_id); - block_id_type block_id_in_preferred_chain = _chain_db->get_block_id_for_num(block_num); - return block_id == block_id_in_preferred_chain; + uint32_t block_num = block_header::num_from_id(block_id); + block_id_type block_id_in_preferred_chain = _chain_db->get_block_id_for_num(block_num); + return block_id == block_id_in_preferred_chain; } /** diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index 507ffd7881..a49d29786e 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -172,16 +172,23 @@ namespace steemit { namespace chain { uint64_t block_log::append( const signed_block& b ) { - my->check_block_write(); - my->check_index_write(); - - uint64_t pos = my->block_stream.tellp(); - fc::raw::pack( my->block_stream, b ); - my->block_stream.write( (char*)&pos, sizeof( pos ) ); - my->index_stream.write( (char*)&pos, sizeof( pos ) ); - my->head = b; - my->head_id = b.id(); - return pos; + try + { + my->check_block_write(); + my->check_index_write(); + + uint64_t pos = my->block_stream.tellp(); + FC_ASSERT( my->index_stream.tellp() == sizeof( uint64_t ) * ( b.block_num() - 1 ), "Append to index file occuring at wrong position.", ( "position", (uint64_t) my->index_stream.tellp() )( "expected",( b.block_num() - 1 ) * sizeof( uint64_t ) ) ); + auto data = fc::raw::pack( b ); + my->block_stream.write( data.data(), data.size() ); + my->block_stream.write( (char*)&pos, sizeof( pos ) ); + my->index_stream.write( (char*)&pos, sizeof( pos ) ); + my->head = b; + my->head_id = b.id(); + + return pos; + } + FC_LOG_AND_RETHROW() } void block_log::flush() @@ -208,7 +215,10 @@ namespace steemit { namespace chain { optional< signed_block > b; uint64_t pos = get_block_pos( block_num ); if( pos != npos ) + { b = read_block( pos ).first; + FC_ASSERT( b->block_num() == block_num , "Wrong block was read from block log.", ( "returned", b->block_num() )( "expected", block_num )); + } return b; } FC_LOG_AND_RETHROW() From fb7756c2b16330a33e208ae23d840ae517533b9b Mon Sep 17 00:00:00 2001 From: JustinW Date: Mon, 2 Jan 2017 23:02:11 +0000 Subject: [PATCH 63/77] updated triggerbuild to match what we're using in jenkins for when we move to multi-branch pipeline project type soon --- ciscripts/triggerbuild.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ciscripts/triggerbuild.sh b/ciscripts/triggerbuild.sh index 18c6be12c0..df308af865 100755 --- a/ciscripts/triggerbuild.sh +++ b/ciscripts/triggerbuild.sh @@ -1,6 +1,8 @@ #!/bin/bash +sh $WORKSPACE/ciscripts/buildpending.sh if sh $WORKSPACE/ciscripts/buildscript.sh; then echo BUILD SUCCESS else echo BUILD FAILURE + exit 1 fi From ecd6449eff52ce1e5cc2d8eec1d6edacc214e4c2 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 09:41:12 -0500 Subject: [PATCH 64/77] Exclude tests and fc in code coverage --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0b8ce58251..37bd96bb77 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,7 +64,7 @@ RUN \ make -j$(nproc) chain_test && \ ./tests/chain_test && \ mkdir -p /var/cobertura && \ - gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude="./tests" --output="/var/cobertura/coverage.xml" && \ + gcovr --object-directory="../" --root=../ --xml-pretty --exclude="./tests" --exclude="./libraries/fc" --output="/var/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From 4bf5af939f120672d159e5e7fafcd3a4993e9059 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 11:30:34 -0500 Subject: [PATCH 65/77] Change directory to exclude --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 37bd96bb77..748e449146 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,7 +64,7 @@ RUN \ make -j$(nproc) chain_test && \ ./tests/chain_test && \ mkdir -p /var/cobertura && \ - gcovr --object-directory="../" --root=../ --xml-pretty --exclude="./tests" --exclude="./libraries/fc" --output="/var/cobertura/coverage.xml" && \ + gcovr --object-directory="../" --root=../ --xml-pretty --exclude="../tests" --exclude="../libraries/fc" --output="/var/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From 2b699b1141bf3ba469f85a91e5a3dfec29afdda9 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 12:10:16 -0500 Subject: [PATCH 66/77] Try a different option --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 748e449146..67e9a47335 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,7 +64,7 @@ RUN \ make -j$(nproc) chain_test && \ ./tests/chain_test && \ mkdir -p /var/cobertura && \ - gcovr --object-directory="../" --root=../ --xml-pretty --exclude="../tests" --exclude="../libraries/fc" --output="/var/cobertura/coverage.xml" && \ + gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude=".*tests.*" --gcov-exclude=".*libraries/fc.*" --output="/var/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From b7431a640d21955e6cad885a6cb676b610dd1bbd Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 13:51:11 -0500 Subject: [PATCH 67/77] Update regex --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 67e9a47335..24c02a7d41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,7 +64,7 @@ RUN \ make -j$(nproc) chain_test && \ ./tests/chain_test && \ mkdir -p /var/cobertura && \ - gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude=".*tests.*" --gcov-exclude=".*libraries/fc.*" --output="/var/cobertura/coverage.xml" && \ + gcovr --object-directory="../" --root=../ --xml-pretty --gcov-exclude=".*tests.*" --gcov-exclude=".*fc.*" --output="/var/cobertura/coverage.xml" && \ cd /usr/local/src/steem && \ rm -rf /usr/local/src/steem/build From f595b8fbd169bb87f8f83ddc8de7a528c0452750 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 15:16:25 -0500 Subject: [PATCH 68/77] Fix failure when parsing a string with precision 0. Added more tests for corner cases #102 --- libraries/protocol/asset.cpp | 11 ++++++----- tests/tests/serialization_tests.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libraries/protocol/asset.cpp b/libraries/protocol/asset.cpp index d03325e6d7..670febd020 100644 --- a/libraries/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -80,22 +80,23 @@ namespace steemit { namespace protocol { result.symbol = uint64_t(0); auto sy = (char*)&result.symbol; - auto intpart = s.substr( 0, dot_pos ); - result.amount = fc::to_int64(intpart); - std::string fractpart; if( dot_pos != std::string::npos ) { FC_ASSERT( space_pos > dot_pos ); + auto intpart = s.substr( 0, dot_pos ); auto fractpart = "1" + s.substr( dot_pos + 1, space_pos - dot_pos - 1 ); result.set_decimals( fractpart.size() - 1 ); + result.amount = fc::to_int64( intpart ); result.amount.value *= result.precision(); - result.amount.value += fc::to_int64(fractpart); + result.amount.value += fc::to_int64( fractpart ); result.amount.value -= result.precision(); } else { + auto intpart = s.substr( 0, space_pos ); + result.amount = fc::to_int64( intpart ); result.set_decimals( 0 ); } auto symbol = s.substr( space_pos + 1 ); @@ -109,7 +110,7 @@ namespace steemit { namespace protocol { return result; } - FC_CAPTURE_LOG_AND_RETHROW( (from) ) + FC_CAPTURE_AND_RETHROW( (from) ) } bool operator == ( const price& a, const price& b ) diff --git a/tests/tests/serialization_tests.cpp b/tests/tests/serialization_tests.cpp index bd15217086..6e3390590d 100644 --- a/tests/tests/serialization_tests.cpp +++ b/tests/tests/serialization_tests.cpp @@ -127,6 +127,7 @@ BOOST_AUTO_TEST_CASE( asset_test ) BOOST_CHECK_EQUAL( tmp.amount.value, 56 ); BOOST_CHECK( std::abs( steem.to_real() - 123.456 ) < 0.0005 ); + BOOST_CHECK_EQUAL( steem.amount.value, 123456 ); BOOST_CHECK_EQUAL( steem.decimals(), 3 ); BOOST_CHECK_EQUAL( steem.symbol_name(), "TESTS" ); BOOST_CHECK_EQUAL( steem.to_string(), "123.456 TESTS" ); @@ -135,6 +136,7 @@ BOOST_AUTO_TEST_CASE( asset_test ) BOOST_CHECK_EQUAL( asset(50000, STEEM_SYMBOL).to_string(), "50.000 TESTS" ); BOOST_CHECK( std::abs( sbd.to_real() - 654.321 ) < 0.0005 ); + BOOST_CHECK_EQUAL( sbd.amount.value, 654321 ); BOOST_CHECK_EQUAL( sbd.decimals(), 3 ); BOOST_CHECK_EQUAL( sbd.symbol_name(), "TBD" ); BOOST_CHECK_EQUAL( sbd.to_string(), "654.321 TBD" ); @@ -170,6 +172,15 @@ BOOST_AUTO_TEST_CASE( asset_test ) BOOST_CHECK_THROW( asset::from_string( "11111111111111111111111111111111111111111111111 TESTS" ), fc::exception ); BOOST_CHECK_THROW( asset::from_string( "1.1.1 TESTS" ), fc::exception ); BOOST_CHECK_THROW( asset::from_string( "1.abc TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( " TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.333" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1.333 " ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( " " ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( " " ), fc::exception ); + + BOOST_CHECK_EQUAL( asset::from_string( "100 TESTS" ).amount.value, 100 ); } FC_LOG_AND_RETHROW() } From ba8e560800a5ccb9e6f3b300d56e28f66c0c8f8f Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Tue, 3 Jan 2017 15:20:15 -0500 Subject: [PATCH 69/77] Add documentation for confusing test case #102 --- tests/tests/serialization_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests/serialization_tests.cpp b/tests/tests/serialization_tests.cpp index 6e3390590d..1523e15912 100644 --- a/tests/tests/serialization_tests.cpp +++ b/tests/tests/serialization_tests.cpp @@ -161,9 +161,9 @@ BOOST_AUTO_TEST_CASE( asset_test ) BOOST_CHECK_THROW( check_sym(steem), fc::exception ); BOOST_CHECK_THROW( asset::from_string( "1.00000000000000000000 TESTS" ), fc::exception ); BOOST_CHECK_THROW( asset::from_string( "1.000TESTS" ), fc::exception ); - BOOST_CHECK_THROW( asset::from_string( "1. 333 TESTS" ), fc::exception ); + BOOST_CHECK_THROW( asset::from_string( "1. 333 TESTS" ), fc::exception ); // Fails because symbol is '333 TESTS', which is too long BOOST_CHECK_THROW( asset::from_string( "1 .333 TESTS" ), fc::exception ); - asset unusual = asset::from_string( "1. 333 X" ); + asset unusual = asset::from_string( "1. 333 X" ); // Passes because symbol '333 X' is short enough FC_ASSERT( unusual.decimals() == 0 ); FC_ASSERT( unusual.symbol_name() == "333 X" ); BOOST_CHECK_THROW( asset::from_string( "1 .333 X" ), fc::exception ); From b61ce97b16b5db2979513e9c228ac440ca58cb5c Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 5 Jan 2017 08:13:24 -0500 Subject: [PATCH 70/77] Fix total payout calculations #751 --- .../tags/include/steemit/tags/tags_plugin.hpp | 3 +- libraries/plugins/tags/tags_plugin.cpp | 109 ++++++++++-------- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/libraries/plugins/tags/include/steemit/tags/tags_plugin.hpp b/libraries/plugins/tags/include/steemit/tags/tags_plugin.hpp index 5824d1ceaf..a3190a5522 100644 --- a/libraries/plugins/tags/include/steemit/tags/tags_plugin.hpp +++ b/libraries/plugins/tags/include/steemit/tags/tags_plugin.hpp @@ -91,7 +91,6 @@ class tag_object : public object< tag_object_type, tag_object > * be reviewed. */ fc::uint128_t children_rshares2; - asset total_payout = asset( 0, SBD_SYMBOL ); comment_mode mode; account_id_type author; @@ -434,7 +433,7 @@ class tag_api : public std::enable_shared_from_this { FC_API( steemit::tags::tag_api, (get_tags) ); FC_REFLECT( steemit::tags::tag_object, - (id)(tag)(created)(active)(cashout)(net_rshares)(net_votes)(hot)(promoted_balance)(children)(children_rshares2)(total_payout)(mode)(author)(parent)(comment) ) + (id)(tag)(created)(active)(cashout)(net_rshares)(net_votes)(hot)(promoted_balance)(children)(children_rshares2)(mode)(author)(parent)(comment) ) CHAINBASE_SET_INDEX_TYPE( steemit::tags::tag_object, steemit::tags::tag_index ) FC_REFLECT( steemit::tags::tag_stats_object, diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index ef367c9105..2af8227ad5 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -63,7 +63,6 @@ struct operation_visitor { s.comments--; } s.net_votes -= tag.net_votes; - s.total_payout += tag.total_payout; }); } void add_stats( const tag_object& tag, const tag_stats_object& stats )const { @@ -93,6 +92,51 @@ struct operation_visitor { }); } + comment_metadata filter_tags( const comment_object& c ) const + { + comment_metadata meta; + + if( c.json_metadata.size() ) + { + try + { + meta = fc::json::from_string( to_string( c.json_metadata ) ).as< comment_metadata >(); + } + catch( const fc::exception& e ) + { + // Do nothing on malformed json_metadata + } + } + + set< string > lower_tags; + if( c.category != "" ) + meta.tags.insert( fc::to_lower( to_string( c.category ) ) ); + + uint8_t tag_limit = 5; + uint8_t count = 0; + for( const auto& tag : meta.tags ) + { + ++count; + if( count > tag_limit || lower_tags.size() > tag_limit ) + break; + if( tag == "" ) + continue; + lower_tags.insert( fc::to_lower( tag ) ); + } + + /// the universal tag applies to everything safe for work or nsfw with a non-negative payout + if( c.net_rshares >= 0 || + (lower_tags.find( "spam" ) == lower_tags.end() && + lower_tags.find( "test" ) == lower_tags.end() ) ) + { + lower_tags.insert( string() ); /// add it to the universal tag + } + + meta.tags = lower_tags; /// TODO: std::move??? + + return meta; + } + void update_tag( const tag_object& current, const comment_object& comment, double hot )const { const auto& stats = get_stats( current.tag ); @@ -107,7 +151,6 @@ struct operation_visitor { obj.net_votes = comment.net_votes; obj.children_rshares2 = comment.children_rshares2; obj.hot = hot; - obj.total_payout = comment.total_payout_value; obj.mode = comment.mode; if( obj.mode != first_payout ) obj.promoted_balance = 0; @@ -138,7 +181,6 @@ struct operation_visitor { obj.children = comment.children; obj.net_rshares = comment.net_rshares.value; obj.children_rshares2 = comment.children_rshares2; - obj.total_payout = comment.total_payout_value; obj.author = author; obj.mode = comment.mode; }); @@ -173,48 +215,7 @@ struct operation_visitor { try { auto hot = calculate_hot(c, _db.head_block_time() ); - - comment_metadata meta; - - if( c.json_metadata.size() ) - { - try - { - meta = fc::json::from_string( to_string( c.json_metadata ) ).as< comment_metadata >(); - } - catch( const fc::exception& e ) - { - // Do nothing on malformed json_metadata - } - } - - set< string > lower_tags; - if( c.category != "" ) - meta.tags.insert( fc::to_lower( to_string( c.category ) ) ); - - uint8_t tag_limit = 5; - uint8_t count = 0; - for( const auto& tag : meta.tags ) - { - ++count; - if( count > tag_limit || lower_tags.size() > tag_limit ) - break; - if( tag == "" ) - continue; - lower_tags.insert( fc::to_lower( tag ) ); - } - - /// the universal tag applies to everything safe for work or nsfw with a non-negative payout - if( c.net_rshares >= 0 || - (lower_tags.find( "spam" ) == lower_tags.end() && - lower_tags.find( "test" ) == lower_tags.end() ) ) - { - lower_tags.insert( string() ); /// add it to the universal tag - } - - meta.tags = lower_tags; /// TODO: std::move??? - - + auto meta = filter_tags( c ); const auto& comment_idx = _db.get_index< tag_index >().indices().get< by_comment >(); auto citr = comment_idx.lower_bound( c.id ); @@ -352,13 +353,23 @@ struct operation_visitor { } void operator()( const comment_reward_operation& op )const { - const auto& c = _db.get_comment( op.author, op.permlink ); - update_tags( c ); + const auto& c = _db.get_comment( op.author, op.permlink ); + update_tags( c ); + + auto meta = filter_tags( c ); + + for( auto tag : meta.tags ) + { + _db.modify( get_stats( tag ), [&]( tag_stats_object& ts ) + { + ts.total_payout += op.payout; + }); + } } void operator()( const comment_payout_update_operation& op )const { - const auto& c = _db.get_comment( op.author, op.permlink ); - update_tags( c ); + const auto& c = _db.get_comment( op.author, op.permlink ); + update_tags( c ); } template From 23769245f3c2ae11e975db8eb261f383491f3045 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 5 Jan 2017 15:02:22 -0500 Subject: [PATCH 71/77] Update plugin library dependencies in newplugin.py #753 --- programs/util/newplugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util/newplugin.py b/programs/util/newplugin.py index d9be28410a..c778bc441a 100755 --- a/programs/util/newplugin.py +++ b/programs/util/newplugin.py @@ -10,7 +10,7 @@ {plugin_name}_api.cpp ) -target_link_libraries( {plugin_provider}_{plugin_name} steemit_app steemit_chain fc graphene_db ) +target_link_libraries( {plugin_provider}_{plugin_name} steemit_app steemit_chain steemit_protocol ) target_include_directories( {plugin_provider}_{plugin_name} PUBLIC "${{CMAKE_CURRENT_SOURCE_DIR}}/include" ) """, From 489c6c4a40cdad73962b9d8c1279b82809f222e0 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 5 Jan 2017 15:31:09 -0500 Subject: [PATCH 72/77] Bump version to 0.16.1 --- libraries/protocol/include/steemit/protocol/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/protocol/include/steemit/protocol/config.hpp b/libraries/protocol/include/steemit/protocol/config.hpp index 865ee0d4f2..6123d7ee69 100644 --- a/libraries/protocol/include/steemit/protocol/config.hpp +++ b/libraries/protocol/include/steemit/protocol/config.hpp @@ -3,7 +3,7 @@ */ #pragma once -#define STEEMIT_BLOCKCHAIN_VERSION ( version(0, 16, 0) ) +#define STEEMIT_BLOCKCHAIN_VERSION ( version(0, 16, 1) ) #define STEEMIT_BLOCKCHAIN_HARDFORK_VERSION ( hardfork_version( STEEMIT_BLOCKCHAIN_VERSION ) ) #ifdef IS_TEST_NET From f50df041e269f73f2e756faa9f1fd4405d070ab0 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Thu, 5 Jan 2017 15:43:49 -0500 Subject: [PATCH 73/77] Bump fc --- libraries/fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fc b/libraries/fc index 2f202e017c..72cd69bed9 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 2f202e017c2fef0ad622d70b0c04951960037461 +Subproject commit 72cd69bed9c818ea6294019e4911825736b367d4 From 4ae7075d24234d42f972c5fbf8659705923a5740 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Fri, 6 Jan 2017 11:12:10 -0500 Subject: [PATCH 74/77] Refactor comment bandwidth rate limiting to remove possible corner case hard fork --- libraries/chain/steem_evaluator.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index 68d010deb6..b98e15f832 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -405,14 +405,18 @@ void comment_evaluator::do_apply( const comment_operation& o ) } uint16_t reward_weight = STEEMIT_100_PERCENT; - auto post_bandwidth = band->average_bandwidth; - if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) && o.parent_author == STEEMIT_ROOT_POST_PARENT ) + if( o.parent_author == STEEMIT_ROOT_POST_PARENT ) { - auto post_delta_time = std::min( now.sec_since_epoch() - band->last_bandwidth_update.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); - auto old_weight = ( post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - post_delta_time ) ) / STEEMIT_POST_AVERAGE_WINDOW; - post_bandwidth = ( old_weight + STEEMIT_100_PERCENT ); - reward_weight = uint16_t( std::min( ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( post_bandwidth.value * post_bandwidth.value ), uint64_t( STEEMIT_100_PERCENT ) ) ); + auto post_bandwidth = band->average_bandwidth; + + if( _db.has_hardfork( STEEMIT_HARDFORK_0_12__176 ) ) + { + auto post_delta_time = std::min( now.sec_since_epoch() - band->last_bandwidth_update.sec_since_epoch(), STEEMIT_POST_AVERAGE_WINDOW ); + auto old_weight = ( post_bandwidth * ( STEEMIT_POST_AVERAGE_WINDOW - post_delta_time ) ) / STEEMIT_POST_AVERAGE_WINDOW; + post_bandwidth = ( old_weight + STEEMIT_100_PERCENT ); + reward_weight = uint16_t( std::min( ( STEEMIT_POST_WEIGHT_CONSTANT * STEEMIT_100_PERCENT ) / ( post_bandwidth.value * post_bandwidth.value ), uint64_t( STEEMIT_100_PERCENT ) ) ); + } _db.modify( *band, [&]( account_bandwidth_object& b ) { From 0331a80cf46c6d02df0d168cebb93ce1336b9222 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 13 Dec 2016 16:31:50 -0500 Subject: [PATCH 75/77] Quick enable/disable nonce computation for unit tests #760 --- tests/tests/operation_tests.cpp | 58 +++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index cdb7a648f1..f1765c4f30 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -3569,6 +3569,9 @@ BOOST_AUTO_TEST_CASE( change_recovery_account ) FC_LOG_AND_RETHROW() } + +//#define CALCULATE_NONCES + BOOST_AUTO_TEST_CASE( pow2_op ) { try @@ -3586,47 +3589,59 @@ BOOST_AUTO_TEST_CASE( pow2_op ) auto old_block_id = db.head_block_id(); - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce1 = nonce; - idump( (nonce1) );*/ + idump( (nonce1) ); +#else //uint64_t nonce1 = 98; +#endif generate_block(); - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary < target ); uint64_t nonce2 = nonce; - idump( (nonce2) );*/ + idump( (nonce2) ); +#else uint64_t nonce2 = 100; +#endif - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce3 = nonce; - idump( (nonce3) );*/ + idump( (nonce3) ); +#else uint64_t nonce3 = 132; +#endif - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce4 = nonce; - idump( (nonce4) );*/ + idump( (nonce4) ); +#else uint64_t nonce4 = 144; +#endif // Test with nonce that doesn't match work, should fail BOOST_TEST_MESSAGE( "Testing pow with nonce that doesn't match work" ); @@ -3636,7 +3651,7 @@ BOOST_AUTO_TEST_CASE( pow2_op ) pow.work = work; STEEMIT_REQUIRE_THROW( pow.validate(), fc::exception ); - BOOST_TEST_MESSAGE( "Testing failure on inssuficient work" ); + BOOST_TEST_MESSAGE( "Testing failure on insufficient work" ); signed_transaction tx; work.create( db.head_block_id(), "alice", nonce2 ); work.prev_block = db.head_block_id(); @@ -3709,22 +3724,26 @@ BOOST_AUTO_TEST_CASE( pow2_op ) target = db.get_pow_summary_target(); nonce = nonce4; - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( old_block_id, "bob", nonce ); + idump( (work) ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce5 = nonce; - idump( (nonce5) );*/ + idump( (nonce5) ); +#else uint32_t nonce5 = 248; +#endif BOOST_TEST_MESSAGE( "Submit pow from existing account without witness object." ); tx.operations.clear(); tx.signatures.clear(); - work.create( db.head_block_id(), "bob", nonce5 ); + work.create( old_block_id, "bob", nonce5 ); work.prev_block = db.head_block_id(); pow.work = work; pow.new_owner_key.reset(); @@ -3750,26 +3769,31 @@ BOOST_AUTO_TEST_CASE( pow2_op ) target = db.get_pow_summary_target(); - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( old_block_id, "sam", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce6 = nonce; - idump( (nonce6) );*/ + idump( (nonce6) ); +#else uint64_t nonce6 = 336; +#endif - /*do +#ifdef CALCULATE_NONCES + do { nonce++; work.create( old_block_id, "dave", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce7 = nonce; - idump( (nonce7) );*/ + idump( (nonce7) ); +#else uint64_t nonce7 = 344; - +#endif // Test with wrong previous block id BOOST_TEST_MESSAGE( "Submit pow with an old block id" ); From 07e5da91d53e45359a0bc871736babca9ca3ddcc Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 6 Jan 2017 15:50:05 -0500 Subject: [PATCH 76/77] Fix Jenkins return code #762 --- ciscripts/buildscript.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ciscripts/buildscript.sh b/ciscripts/buildscript.sh index 3560706198..c378c8d409 100755 --- a/ciscripts/buildscript.sh +++ b/ciscripts/buildscript.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e export IMAGE_NAME="steemit/steem:${GIT_BRANCH#*/}" if [[ $IMAGE_NAME == "steemit/steem:stable" ]] ; then IMAGE_NAME="steemit/steem:latest" From ae55a1244427bc8f6e2fdd6231cbe1f90f88eb2e Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 9 Jan 2017 09:35:59 -0500 Subject: [PATCH 77/77] Update nonces for 0.16.1 --- tests/tests/operation_tests.cpp | 50 ++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index cdb7a648f1..6d4c02fc58 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -3598,35 +3598,41 @@ BOOST_AUTO_TEST_CASE( pow2_op ) generate_block(); - /*do + /* + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary < target ); uint64_t nonce2 = nonce; - idump( (nonce2) );*/ - uint64_t nonce2 = 100; + idump( (nonce2) ); + //*/ + uint64_t nonce2 = 7; - /*do + /* + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce3 = nonce; - idump( (nonce3) );*/ - uint64_t nonce3 = 132; + idump( (nonce3) ); + //*/ + uint64_t nonce3 = 257; - /*do + /* + do { nonce++; work.create( db.head_block_id(), "alice", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce4 = nonce; - idump( (nonce4) );*/ - uint64_t nonce4 = 144; + idump( (nonce4) ); + //*/ + uint64_t nonce4 = 262; // Test with nonce that doesn't match work, should fail BOOST_TEST_MESSAGE( "Testing pow with nonce that doesn't match work" ); @@ -3709,15 +3715,17 @@ BOOST_AUTO_TEST_CASE( pow2_op ) target = db.get_pow_summary_target(); nonce = nonce4; - /*do + /* + do { nonce++; - work.create( old_block_id, "bob", nonce ); + work.create( db.head_block_id(), "bob", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce5 = nonce; - idump( (nonce5) );*/ - uint32_t nonce5 = 248; + idump( (nonce5) ); + //*/ + uint32_t nonce5 = 365; BOOST_TEST_MESSAGE( "Submit pow from existing account without witness object." ); @@ -3750,25 +3758,29 @@ BOOST_AUTO_TEST_CASE( pow2_op ) target = db.get_pow_summary_target(); - /*do + /* + do { nonce++; work.create( old_block_id, "sam", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce6 = nonce; - idump( (nonce6) );*/ - uint64_t nonce6 = 336; + idump( (nonce6) ); + //*/ + uint64_t nonce6 = 373; - /*do + /* + do { nonce++; work.create( old_block_id, "dave", nonce ); idump( (work.proof.is_valid())(work.pow_summary)(target) ); } while( !work.proof.is_valid() || work.pow_summary >= target ); uint64_t nonce7 = nonce; - idump( (nonce7) );*/ - uint64_t nonce7 = 344; + idump( (nonce7) ); + //*/ + uint64_t nonce7 = 406; // Test with wrong previous block id