Cache hash for multiple block->hash () calls (#2536)

This commit is contained in:
Wesley Shillingford 2020-02-04 20:33:31 +00:00 committed by GitHub
commit 1690a264ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 3 deletions

View file

@ -366,25 +366,36 @@ TEST (state_block, hashing)
nano::keypair key;
nano::state_block block (key.pub, 0, key.pub, 0, 0, key.prv, key.pub, 0);
auto hash (block.hash ());
ASSERT_EQ (hash, block.hash ()); // check cache works
block.hashables.account.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_NE (hash, block.hash ());
block.hashables.account.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_EQ (hash, block.hash ());
block.hashables.previous.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_NE (hash, block.hash ());
block.hashables.previous.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_EQ (hash, block.hash ());
block.hashables.representative.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_NE (hash, block.hash ());
block.hashables.representative.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_EQ (hash, block.hash ());
block.hashables.balance.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_NE (hash, block.hash ());
block.hashables.balance.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_EQ (hash, block.hash ());
block.hashables.link.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_NE (hash, block.hash ());
block.hashables.link.bytes[0] ^= 0x1;
block.refresh ();
ASSERT_EQ (hash, block.hash ());
}

View file

@ -58,6 +58,7 @@ TEST (bulk_pull, end_not_owned)
open.hashables.account = key2.pub;
open.hashables.representative = key2.pub;
open.hashables.source = latest;
open.refresh ();
open.signature = nano::sign_message (key2.prv, key2.pub, open.hash ());
system.nodes[0]->work_generate_blocking (open);
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->process (open).code);

View file

@ -76,7 +76,7 @@ size_t nano::block::size (nano::block_type type_a)
return result;
}
nano::block_hash nano::block::hash () const
nano::block_hash nano::block::generate_hash () const
{
nano::block_hash result;
blake2b_state hash_l;
@ -88,6 +88,30 @@ nano::block_hash nano::block::hash () const
return result;
}
void nano::block::refresh ()
{
if (!cached_hash.is_zero ())
{
cached_hash = generate_hash ();
}
}
nano::block_hash const & nano::block::hash () const
{
if (!cached_hash.is_zero ())
{
// Once a block is created, it should not be modified (unless using refresh ())
// This would invalidate the cache; check it hasn't changed.
assert (cached_hash == generate_hash ());
}
else
{
cached_hash = generate_hash ();
}
return cached_hash;
}
nano::block_hash nano::block::full_hash () const
{
nano::block_hash result;

View file

@ -57,7 +57,7 @@ class block
{
public:
// Return a digest of the hashables in this block.
nano::block_hash hash () const;
nano::block_hash const & hash () const;
// Return a digest of hashables and non-hashables in this block.
nano::block_hash full_hash () const;
std::string to_json () const;
@ -88,6 +88,14 @@ public:
virtual ~block () = default;
virtual bool valid_predecessor (nano::block const &) const = 0;
static size_t size (nano::block_type);
// If there are any changes to the hashables, call this to update the cached hash
void refresh ();
protected:
mutable nano::block_hash cached_hash{ 0 };
private:
nano::block_hash generate_hash () const;
};
class send_hashables
{

View file

@ -99,7 +99,7 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran
// Calculate votes for local representatives
if (representative)
{
this->node.block_processor.generator.add (block->hash ());
this->node.block_processor.generator.add (info.head);
}
}
}