Esempio n. 1
0
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());
}
Esempio n. 2
0
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]));
}