ceremonyclient/hypergraph/atom.go
Cassandra Heart dbd95bd9e9
v2.1.0 (#439)
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete

* 2.1.0 main node rollup
2025-09-30 02:48:15 -05:00

103 lines
2.4 KiB
Go

package hypergraph
import (
"math/big"
"github.com/prometheus/client_golang/prometheus"
"source.quilibrium.com/quilibrium/monorepo/types/hypergraph"
"source.quilibrium.com/quilibrium/monorepo/types/tries"
)
// AtomFromBytes deserializes an atom from its byte representation.
// The first byte indicates the type: 0x00 for vertex, anything else for
// hyperedge. Returns nil if the data is invalid.
func AtomFromBytes(data []byte) hypergraph.Atom {
if len(data) == 0 {
return nil
}
if data[0] == 0x00 {
// Vertex format: [type(1)][appAddr(32)][dataAddr(32)]
// [commitment(var)][size(32)]
if len(data) < 161 {
return nil
}
return &vertex{
appAddress: [32]byte(data[1:33]),
dataAddress: [32]byte(data[33:65]),
commitment: data[65 : len(data)-32],
size: new(big.Int).SetBytes(data[len(data)-32:]),
}
} else {
// Hyperedge format: [type(1)][appAddr(32)][dataAddr(32)]
// [tree(var)]
if len(data) < 65 {
return nil
}
tree, err := tries.DeserializeNonLazyTree(data[65:])
if err != nil {
return nil
}
// Validate all leaves in the tree
leaves := tries.GetAllPreloadedLeaves(tree.Root)
for _, leaf := range leaves {
if len(leaf.Key) != 64 {
return nil
}
a := AtomFromBytes(leaf.Value)
if a == nil {
return nil
}
if leaf.Size == nil || leaf.Size.Cmp(a.GetSize()) != 0 {
return nil
}
}
return &hyperedge{
appAddress: [32]byte(data[1:33]),
dataAddress: [32]byte(data[33:65]),
extTree: tree,
}
}
}
// LookupAtom checks if an atom (vertex or hyperedge) exists in the hypergraph.
// Dispatches to LookupVertex or LookupHyperedge based on the atom type.
func (hg *HypergraphCRDT) LookupAtom(a hypergraph.Atom) bool {
timer := prometheus.NewTimer(LookupDuration.WithLabelValues("atom"))
defer timer.ObserveDuration()
var atomType string
var found bool
switch v := a.(type) {
case *vertex:
atomType = "vertex"
found = hg.LookupVertex(v)
case *hyperedge:
atomType = "hyperedge"
found = hg.LookupHyperedge(v)
default:
atomType = "unknown"
found = false
}
LookupAtomTotal.WithLabelValues(atomType, boolToString(found)).Inc()
return found
}
// LookupAtomSet checks if all atoms in a set exist in the hypergraph. Returns
// true only if all atoms are present.
func (hg *HypergraphCRDT) LookupAtomSet(atomSet []hypergraph.Atom) bool {
for _, atom := range atomSet {
if !hg.LookupAtom(atom) {
return false
}
}
return true
}