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 );