diff --git a/rai/node/node.cpp b/rai/node/node.cpp index d1188d2a..bf31ed12 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -3674,22 +3674,28 @@ void rai::active_transactions::announce_votes () if there are less than 100 active elections */ if (i->announcements % announcement_long == 1 && roots.size () < 100) { + std::unique_ptr previous (nullptr); auto previous_hash (election_l->status.winner->previous ()); if (!previous_hash.is_zero ()) { - auto previous (node.store.block_get (transaction, previous_hash)); + previous = node.store.block_get (transaction, previous_hash); if (previous != nullptr) { add (std::make_pair (std::move (previous), nullptr)); } } - auto source_hash (node.ledger.block_source (transaction, *election_l->status.winner)); - if (!source_hash.is_zero ()) + /* If previous block not existing/not commited yet, block_source can cause segfault for state blocks + So source check can be done only if previous != nullptr or previous is 0 (open account) */ + if (previous_hash.is_zero () || previous != nullptr) { - auto source (node.store.block_get (transaction, source_hash)); - if (source != nullptr) + auto source_hash (node.ledger.block_source (transaction, *election_l->status.winner)); + if (!source_hash.is_zero ()) { - add (std::make_pair (std::move (source), nullptr)); + auto source (node.store.block_get (transaction, source_hash)); + if (source != nullptr) + { + add (std::make_pair (std::move (source), nullptr)); + } } } } diff --git a/rai/secure/ledger.cpp b/rai/secure/ledger.cpp index fedbdfff..7348658f 100644 --- a/rai/secure/ledger.cpp +++ b/rai/secure/ledger.cpp @@ -729,6 +729,13 @@ rai::block_hash rai::ledger::block_destination (rai::transaction const & transac rai::block_hash rai::ledger::block_source (rai::transaction const & transaction_a, rai::block const & block_a) { + /* + * block_source() requires that the previous block of the block + * passed in exist in the database. This is because it will try + * to check account balances to determine if it is a send block. + */ + assert (block_a.previous ().is_zero () || store.block_exists (transaction_a, block_a.previous ())); + // If block_a.source () is nonzero, then we have our source. // However, universal blocks will always return zero. rai::block_hash result (block_a.source ());