From 18a99584a271845e94fbaadc1ca75d5f481adedc Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 30 Jun 2015 18:40:46 -0400 Subject: [PATCH] Start #116 Index Version Checking - adding changes for #115 that didn't make the last commit --- libraries/chain/CMakeLists.txt | 1 + libraries/chain/db_block.cpp | 4 ++-- .../graphene/chain/balance_evaluator.hpp | 4 ++-- .../chain/transaction_evaluation_state.hpp | 9 ++++---- libraries/chain/proposal_object.cpp | 2 +- .../chain/transaction_evaluation_state.cpp | 23 ++++++++++++++++++- libraries/db/include/graphene/db/index.hpp | 19 ++++++++++++++- 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index 9c048a13..5dce1cb7 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -6,6 +6,7 @@ add_library( graphene_chain type_id.cpp address.cpp + pts_address.cpp asset.cpp predicate.cpp diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index bc26f5a9..6c749a8e 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -453,7 +453,7 @@ processed_transaction database::_apply_transaction( const signed_transaction& tr eval_state._sigs.reserve( trx.signatures.size() ); for( const auto& sig : trx.signatures ) - FC_ASSERT( eval_state._sigs.insert( std::make_pair( address(fc::ecc::public_key( sig, trx.digest() )), false) ).second, "Multiple signatures by same key detected" ) ; + FC_ASSERT( eval_state._sigs.insert( std::make_pair( public_key_type(fc::ecc::public_key( sig, trx.digest() )), false) ).second, "Multiple signatures by same key detected" ) ; } //If we're skipping tapos check, but not dupe check, assume all transactions have maximum expiration time. @@ -532,7 +532,7 @@ processed_transaction database::_apply_transaction( const signed_transaction& tr for( const auto& sig : trx.signatures ) FC_ASSERT(eval_state._sigs.insert( - std::make_pair(address(fc::ecc::public_key(sig, trx.digest(tapos_block_summary.block_id) )), + std::make_pair(public_key_type(fc::ecc::public_key(sig, trx.digest(tapos_block_summary.block_id) )), false)).second, "Multiple signatures by same key detected"); } diff --git a/libraries/chain/include/graphene/chain/balance_evaluator.hpp b/libraries/chain/include/graphene/chain/balance_evaluator.hpp index 3a96cde0..6b2c8b22 100644 --- a/libraries/chain/include/graphene/chain/balance_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/balance_evaluator.hpp @@ -21,8 +21,8 @@ public: database& d = db(); balance = &op.balance_to_claim(d); - FC_ASSERT(trx_state->_sigs.count(balance->owner) == 1); - trx_state->_sigs[balance->owner] = true; + + FC_ASSERT(trx_state->signed_by( balance->owner, true /*maybe pts*/ )); FC_ASSERT(op.total_claimed.asset_id == balance->asset_type()); if( balance->vesting_policy.valid() ) { diff --git a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp index 32f27d0b..7c0ececd 100644 --- a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp +++ b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp @@ -41,6 +41,7 @@ namespace graphene { namespace chain { database& db()const { FC_ASSERT( _db ); return *_db; } bool signed_by( key_id_type id ); + bool signed_by( const address& a, bool maybe_pts = false ); /** derived from signatures on transaction flat_set
signed_by; @@ -56,9 +57,9 @@ namespace graphene { namespace chain { /** When an address is referenced via check authority it is flagged as being used, * all addresses must be flagged as being used or the transaction will fail. */ - flat_map _sigs; - const signed_transaction* _trx = nullptr; - database* _db = nullptr; - bool _is_proposed_trx = false; + flat_map _sigs; + const signed_transaction* _trx = nullptr; + database* _db = nullptr; + bool _is_proposed_trx = false; }; } } // namespace graphene::chain diff --git a/libraries/chain/proposal_object.cpp b/libraries/chain/proposal_object.cpp index 28d80b70..996290c8 100644 --- a/libraries/chain/proposal_object.cpp +++ b/libraries/chain/proposal_object.cpp @@ -38,7 +38,7 @@ bool proposal_object::is_authorized_to_execute(database& db) const signed_transaction tmp; dry_run_eval._trx = &tmp; for( auto key_id : available_key_approvals ) - dry_run_eval._sigs.insert( std::make_pair(key_id(db).key_address(),true) ); + dry_run_eval._sigs.insert( std::make_pair(key_id(db).key(),true) ); //insert into dry_run_eval->_trx.signatures //dry_run_eval.signed_by.insert(available_key_approvals.begin(), available_key_approvals.end()); diff --git a/libraries/chain/transaction_evaluation_state.cpp b/libraries/chain/transaction_evaluation_state.cpp index 4a11c1f9..e0e8fba4 100644 --- a/libraries/chain/transaction_evaluation_state.cpp +++ b/libraries/chain/transaction_evaluation_state.cpp @@ -99,10 +99,31 @@ namespace graphene { namespace chain { assert(_trx); assert(_db); //wdump((_sigs)(id(*_db).key_address())(*_trx) ); - auto itr = _sigs.find( id(*_db).key_address() ); + auto itr = _sigs.find( id(*_db).key() ); if( itr != _sigs.end() ) return itr->second = true; return false; } + bool transaction_evaluation_state::signed_by( const address& a, bool maybe_pts ) + { + if( _db->get_node_properties().skip_flags & (database::skip_authority_check|database::skip_transaction_signatures) ) + return true; + for( auto itr = _sigs.begin(); itr != _sigs.end(); ++itr ) + { + if( itr->first == a ) return itr->second = true; + if( maybe_pts ) + { + //pts normal + if( pts_address( itr->first, false, 56 ) == a ) return itr->second = true; + //pts compressed + if( pts_address( itr->first, true, 56 ) == a ) return itr->second = true; + // btc normal + if( pts_address( itr->first, false, 0 ) == a ) return itr->second = true; + // btc compressed + if( pts_address( itr->first, true, 0 ) == a ) return itr->second = true; + } + } + return false; + } } } // namespace graphene::chain diff --git a/libraries/db/include/graphene/db/index.hpp b/libraries/db/include/graphene/db/index.hpp index 51e79e73..89e8aafe 100644 --- a/libraries/db/include/graphene/db/index.hpp +++ b/libraries/db/include/graphene/db/index.hpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include namespace graphene { namespace db { @@ -205,13 +207,26 @@ namespace graphene { namespace db { virtual void use_next_id()override { ++_next_id.number; } virtual void set_next_id( object_id_type id )override { _next_id = id; } + fc::sha256 get_object_version()const + { + // TODO: use something other than json to describe the type and detect changes in serialization + // json will only detect adding, removing, or renaming fields but will not detect changing types + // or changes in the contents of optional values. + auto json_obj = fc::json::to_string( object_type() ); + return fc::sha256::hash(json_obj); + } + virtual void open( const path& db )override { if( !fc::exists( db ) ) return; fc::file_mapping fm( db.generic_string().c_str(), fc::read_only ); fc::mapped_region mr( fm, fc::read_only, 0, fc::file_size(db) ); fc::datastream ds( (const char*)mr.get_address(), mr.get_size() ); + fc::sha256 open_ver; + fc::raw::unpack(ds, _next_id); + fc::raw::unpack(ds, open_ver); + FC_ASSERT( open_ver == get_object_version(), "Incompatible Version, the serialization of objects in this index has changed" ); try { vector tmp; while( true ) @@ -227,7 +242,9 @@ namespace graphene { namespace db { std::ofstream out( db.generic_string(), std::ofstream::binary | std::ofstream::out | std::ofstream::trunc ); FC_ASSERT( out ); - out.write( (char*)&_next_id, sizeof(_next_id) ); + auto ver = get_object_version(); + fc::raw::pack( out, _next_id ); + fc::raw::pack( out, ver ); this->inspect_all_objects( [&]( const object& o ) { auto vec = fc::raw::pack( static_cast(o) ); auto packed_vec = fc::raw::pack( vec );