From 72c0d21fc6bf60a05a6026f5a4805970c66d633e Mon Sep 17 00:00:00 2001
From: Peter Conrad <conrad@quisquis.de>
Date: Mon, 17 Sep 2018 19:33:27 +0200
Subject: [PATCH 1/5] Avoid useless hash calculations

---
 libraries/chain/db_block.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp
index e2d4dad980..efc5562a89 100644
--- a/libraries/chain/db_block.cpp
+++ b/libraries/chain/db_block.cpp
@@ -626,9 +626,12 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
 
    auto& trx_idx = get_mutable_index_type<transaction_index>();
    const chain_id_type& chain_id = get_chain_id();
-   auto trx_id = trx.id();
-   FC_ASSERT( (skip & skip_transaction_dupe_check) ||
-              trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() );
+   transaction_id_type trx_id;
+   if( !(skip & skip_transaction_dupe_check) )
+   {
+      trx_id = trx.id();
+      FC_ASSERT( trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() );
+   }
    transaction_evaluation_state eval_state(this);
    const chain_parameters& chain_parameters = get_global_properties().parameters;
    eval_state._trx = &trx;
@@ -662,7 +665,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
    //Insert transaction into unique transactions database.
    if( !(skip & skip_transaction_dupe_check) )
    {
-      create<transaction_object>([&](transaction_object& transaction) {
+      create<transaction_object>([&trx_id,&trx](transaction_object& transaction) {
          transaction.trx_id = trx_id;
          transaction.trx = trx;
       });

From 5e1af9ec698a7fd34654946dff246111052f1940 Mon Sep 17 00:00:00 2001
From: Peter Conrad <conrad@quisquis.de>
Date: Fri, 28 Sep 2018 15:49:53 +0200
Subject: [PATCH 2/5] Skip merkle tree check during replay

---
 libraries/chain/db_management.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp
index daf8911614..c54e69f3cf 100644
--- a/libraries/chain/db_management.cpp
+++ b/libraries/chain/db_management.cpp
@@ -76,6 +76,7 @@ void database::reindex( fc::path data_dir )
 
    uint32_t skip = skip_witness_signature |
                    skip_block_size_check |
+                   skip_merkle_check |
                    skip_transaction_signatures |
                    skip_transaction_dupe_check |
                    skip_tapos_check |

From b2bafa46103643d0362bdbc7ccb53cedcf92a484 Mon Sep 17 00:00:00 2001
From: Peter Conrad <conrad@quisquis.de>
Date: Mon, 17 Sep 2018 19:38:35 +0200
Subject: [PATCH 3/5] Enable tx dupe check at end of replay

---
 libraries/chain/db_management.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp
index c54e69f3cf..7cb52ba409 100644
--- a/libraries/chain/db_management.cpp
+++ b/libraries/chain/db_management.cpp
@@ -85,6 +85,8 @@ void database::reindex( fc::path data_dir )
 
    size_t total_processed_block_size;
    size_t total_block_size = _block_id_to_block.total_block_size();
+   const auto& gpo = get_global_properties();
+   const fc::time_point_sec now( fc::time_point::now() );
    for( uint32_t i = head_block_num() + 1; i <= last_block_num; ++i )
    {
       if( i % 10000 == 0 ) 
@@ -107,6 +109,8 @@ void database::reindex( fc::path data_dir )
          flush();
          ilog( "Done" );
       }
+      if( head_block_time() >= now - gpo.parameters.maximum_time_until_expiration )
+         skip &= ~skip_transaction_dupe_check;
       fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
       if( !block.valid() )
       {

From 4e6d2d4f54e3acd7a7894db3d11b0050afc81700 Mon Sep 17 00:00:00 2001
From: Peter Conrad <conrad@quisquis.de>
Date: Thu, 27 Sep 2018 20:23:51 +0200
Subject: [PATCH 4/5] Use cheaper comparison for public_key sets + maps

---
 libraries/chain/account_object.cpp                 |  6 +++---
 .../include/graphene/chain/account_object.hpp      | 14 +++++++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libraries/chain/account_object.cpp b/libraries/chain/account_object.cpp
index 87f52cafd2..952a4c7c2c 100644
--- a/libraries/chain/account_object.cpp
+++ b/libraries/chain/account_object.cpp
@@ -121,9 +121,9 @@ set<account_id_type> account_member_index::get_account_members(const account_obj
       result.insert(auth.first);
    return result;
 }
-set<public_key_type> account_member_index::get_key_members(const account_object& a)const
+set<public_key_type, account_member_index::key_compare> account_member_index::get_key_members(const account_object& a)const
 {
-   set<public_key_type> result;
+   set<public_key_type, key_compare> result;
    for( auto auth : a.owner.key_auths )
       result.insert(auth.first);
    for( auto auth : a.active.key_auths )
@@ -215,7 +215,7 @@ void account_member_index::object_modified(const object& after)
 
 
     {
-       set<public_key_type> after_key_members = get_key_members(a);
+       set<public_key_type, key_compare> after_key_members = get_key_members(a);
 
        vector<public_key_type> removed; removed.reserve(before_key_members.size());
        std::set_difference(before_key_members.begin(), before_key_members.end(),
diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp
index 02cadc09cb..9291cec83b 100644
--- a/libraries/chain/include/graphene/chain/account_object.hpp
+++ b/libraries/chain/include/graphene/chain/account_object.hpp
@@ -292,6 +292,14 @@ namespace graphene { namespace chain {
     */
    class account_member_index : public secondary_index
    {
+      class key_compare {
+      public:
+         inline bool operator()( const public_key_type& a, const public_key_type& b )const
+         {
+            return a.key_data < b.key_data;
+         }
+      };
+
       public:
          virtual void object_inserted( const object& obj ) override;
          virtual void object_removed( const object& obj ) override;
@@ -301,18 +309,18 @@ namespace graphene { namespace chain {
 
          /** given an account or key, map it to the set of accounts that reference it in an active or owner authority */
          map< account_id_type, set<account_id_type> > account_to_account_memberships;
-         map< public_key_type, set<account_id_type> > account_to_key_memberships;
+         map< public_key_type, set<account_id_type>, key_compare > account_to_key_memberships;
          /** some accounts use address authorities in the genesis block */
          map< address, set<account_id_type> >         account_to_address_memberships;
 
 
       protected:
          set<account_id_type>  get_account_members( const account_object& a )const;
-         set<public_key_type>  get_key_members( const account_object& a )const;
+         set<public_key_type, key_compare>  get_key_members( const account_object& a )const;
          set<address>          get_address_members( const account_object& a )const;
 
          set<account_id_type>  before_account_members;
-         set<public_key_type>  before_key_members;
+         set<public_key_type, key_compare>  before_key_members;
          set<address>          before_address_members;
    };
 

From e9f273dbe817140f3e07a6cb06f8c7ae767e098c Mon Sep 17 00:00:00 2001
From: Peter Conrad <conrad@quisquis.de>
Date: Sat, 6 Oct 2018 14:51:22 +0200
Subject: [PATCH 5/5] Enable tx dupe check a little earlier

---
 libraries/chain/db_management.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp
index 7cb52ba409..6f627adb55 100644
--- a/libraries/chain/db_management.cpp
+++ b/libraries/chain/db_management.cpp
@@ -86,7 +86,6 @@ void database::reindex( fc::path data_dir )
    size_t total_processed_block_size;
    size_t total_block_size = _block_id_to_block.total_block_size();
    const auto& gpo = get_global_properties();
-   const fc::time_point_sec now( fc::time_point::now() );
    for( uint32_t i = head_block_num() + 1; i <= last_block_num; ++i )
    {
       if( i % 10000 == 0 ) 
@@ -109,7 +108,7 @@ void database::reindex( fc::path data_dir )
          flush();
          ilog( "Done" );
       }
-      if( head_block_time() >= now - gpo.parameters.maximum_time_until_expiration )
+      if( head_block_time() >= last_block->timestamp - gpo.parameters.maximum_time_until_expiration )
          skip &= ~skip_transaction_dupe_check;
       fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
       if( !block.valid() )