Files
ark/common/tree/congestion_tree.go
Louis Singer 5dba216a98 Congestion tree validation (#84)
* add common/pkg/tree validation

* update noah go.mod

* cleaning and fixes

* fix builder_test.go

* Fix deferred func

* fix even number of vtxos in congestion tree

---------

Co-authored-by: altafan <18440657+altafan@users.noreply.github.com>
2024-01-23 15:38:43 +01:00

98 lines
2.0 KiB
Go

package tree
import "errors"
// Node is a struct embedding the transaction and the parent txid of a congestion tree node
type Node struct {
Txid string
Tx string
ParentTxid string
Leaf bool
}
var (
ErrParentNotFound = errors.New("parent not found")
ErrLeafNotFound = errors.New("leaf not found in congestion tree")
)
// CongestionTree is reprensented as a matrix of TreeNode struct
// the first level of the matrix is the root of the tree
type CongestionTree [][]Node
// Leaves returns the leaves of the congestion tree (the vtxos txs)
func (c CongestionTree) Leaves() []Node {
leaves := c[len(c)-1]
for _, level := range c[:len(c)-1] {
for _, node := range level {
if node.Leaf {
leaves = append(leaves, node)
}
}
}
return leaves
}
// Children returns all the nodes that have the given node as parent
func (c CongestionTree) Children(nodeTxid string) []Node {
var children []Node
for _, level := range c {
for _, node := range level {
if node.ParentTxid == nodeTxid {
children = append(children, node)
}
}
}
return children
}
func (c CongestionTree) NumberOfNodes() int {
var count int
for _, level := range c {
count += len(level)
}
return count
}
func (c CongestionTree) Branch(vtxoTxid string) ([]Node, error) {
branch := make([]Node, 0)
leaves := c.Leaves()
// check if the vtxo is a leaf
found := false
for _, leaf := range leaves {
if leaf.Txid == vtxoTxid {
found = true
branch = append(branch, leaf)
break
}
}
if !found {
return nil, ErrLeafNotFound
}
rootTxid := c[0][0].Txid
for branch[0].Txid != rootTxid {
parent, err := branch[0].findParent(c)
if err != nil {
return nil, err
}
branch = append([]Node{parent}, branch...)
}
return branch, nil
}
func (n Node) findParent(tree CongestionTree) (Node, error) {
for _, level := range tree {
for _, node := range level {
if node.Txid == n.ParentTxid {
return node, nil
}
}
}
return Node{}, ErrParentNotFound
}