func (m *CPPMerkleTree) RootAtSnapshot(snapshot uint64) ([]byte, error) {
	hash := make([]byte, m.nodeSize)
	success := C.RootAtSnapshot(m.peer, C.BYTE_SLICE(&hash), C.size_t(snapshot))
	if !success {
		return nil, fmt.Errorf("failed to get root at snapshot %d", snapshot)
	}
	return hash, nil
}
func (m *CPPMerkleTree) CurrentRoot() ([]byte, error) {
	hash := make([]byte, m.nodeSize)
	success := C.CurrentRoot(m.peer, C.BYTE_SLICE(&hash))
	if !success {
		return nil, errors.New("failed to get current root")
	}
	return hash, nil
}
func (m *CPPMerkleTree) LeafHash(leaf uint64) ([]byte, error) {
	hash := make([]byte, m.nodeSize)
	success := C.LeafHash(m.peer, C.BYTE_SLICE(&hash), C.size_t(leaf))
	if !success {
		return nil, fmt.Errorf("failed to get leafhash of leaf %d", leaf)
	}
	return hash, nil
}
func (m *CPPMerkleTree) PathToRootAtSnapshot(leaf, snapshot uint64) ([][]byte, error) {
	var num_entries C.size_t
	entryBuffer := make([]byte, C.size_t(m.LevelCount())*m.nodeSize)
	success := C.PathToRootAtSnapshot(m.peer, C.BYTE_SLICE(&entryBuffer), &num_entries, C.size_t(leaf), C.size_t(snapshot))
	if !success {
		return nil, fmt.Errorf("failed to get path to root at snapshot %d from leaf %d", snapshot, leaf)
	}
	return splitSlice(entryBuffer, int(m.nodeSize))
}
func (m *CPPMerkleTree) PathToCurrentRoot(leaf uint64) ([][]byte, error) {
	var numEntries C.size_t
	entryBuffer := make([]byte, C.size_t(m.LevelCount())*m.nodeSize)
	success := C.PathToCurrentRoot(m.peer, C.BYTE_SLICE(&entryBuffer), &numEntries, C.size_t(leaf))
	if !success {
		return nil, fmt.Errorf("failed to get path to current root from leaf %d", leaf)
	}
	return splitSlice(entryBuffer, int(m.nodeSize))
}
func (m *CPPMerkleTree) SnapshotConsistency(snapshot1, snapshot2 uint64) ([][]byte, error) {
	var num_entries C.size_t
	entryBuffer := make([]byte, C.size_t(m.LevelCount())*m.nodeSize)
	success := C.SnapshotConsistency(m.peer, C.BYTE_SLICE(&entryBuffer), &num_entries, C.size_t(snapshot1), C.size_t(snapshot2))
	if !success {
		return nil, fmt.Errorf("failed to get path to snapshot consistency from %d to %d", snapshot1, snapshot2)
	}
	return splitSlice(entryBuffer, int(m.nodeSize))
}
func (m *CPPMerkleTree) AddLeafHash(hash []byte) uint64 {
	return uint64(C.AddLeafHash(m.peer, C.BYTE_SLICE(&hash)))
}
func (m *CPPMerkleTree) AddLeaf(leaf []byte) uint64 {
	return uint64(C.AddLeaf(m.peer, C.BYTE_SLICE(&leaf)))
}