ptree_branch::ptree_branch(uint8_t split_pos, const ptree_ptr& p1, const ptree_ptr& p2) : m_branches{ p1, p2 } , m_node_count(p1->node_count() + p2->node_count()) , m_split_pos(split_pos) , m_complete(p1->complete() && p2->complete()) { if (p1->is_proxy()) { // p1 is proxy, p2 must be valid, and branches are in order m_prefix = p2->prefix(); } else if (p2->is_proxy()) { // p2 is proxy, p1 must be valid, and branches are in order m_prefix = p1->prefix(); } else { // Both are valid, but might be out of order m_prefix = p1->prefix(); if (p1->prefix() > p2->prefix()) { swap(m_branches[0], m_branches[1]); } } m_prefix.zero_above(split_pos); m_merkle = make_digest(m_prefix, m_node_count, m_branches[0]->merkle(), m_branches[1]->merkle()); }
ptree_ptr ptree_branch::merge(ptree_ptr other) const { if (m_merkle != other->merkle()) { // If there is a mismatch, fail hard return ptree_ptr(); } if (complete() || other->is_proxy()) { // If I am complete, or the other side is a proxy // pick this entry return shared_from_this(); } // At this point, othe side should be a branch shared_ptr<const ptree_branch> obranch = std::dynamic_pointer_cast<const ptree_branch>(other); if (!obranch) { // If not, fail return ptree_ptr(); } // Merge both children return make_shared<ptree_branch>(m_split_pos, m_branches[0]->merge(obranch->m_branches[0]), m_branches[1]->merge(obranch->m_branches[1])); }