mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 18:37:26 +08:00
177 lines
4.4 KiB
Go
177 lines
4.4 KiB
Go
package global
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/pkg/errors"
|
|
hgstate "source.quilibrium.com/quilibrium/monorepo/node/execution/state/hypergraph"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/execution/intrinsics"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/hypergraph"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/schema"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/tries"
|
|
)
|
|
|
|
// UpdateAggregateProverStatus updates the prover status based on the aggregate
|
|
// status of all allocations
|
|
func UpdateAggregateProverStatus(
|
|
hg *hgstate.HypergraphState,
|
|
proverAddress []byte,
|
|
frameNumber uint64,
|
|
proverTree *tries.VectorCommitmentTree,
|
|
rdfMultiprover *schema.RDFMultiprover,
|
|
) error {
|
|
// Get the hyperedge to check all allocations
|
|
hyperedgeAddress := [64]byte{}
|
|
copy(hyperedgeAddress[:32], intrinsics.GLOBAL_INTRINSIC_ADDRESS[:])
|
|
copy(hyperedgeAddress[32:], proverAddress)
|
|
|
|
hyperedge, err := hg.Get(
|
|
hyperedgeAddress[:32],
|
|
hyperedgeAddress[32:],
|
|
hgstate.HyperedgeAddsDiscriminator,
|
|
)
|
|
if err != nil || hyperedge == nil {
|
|
// No hyperedge means no allocations, prover should be left (4)
|
|
return rdfMultiprover.Set(
|
|
GLOBAL_RDF_SCHEMA,
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS[:],
|
|
"prover:Prover",
|
|
"Status",
|
|
[]byte{4},
|
|
proverTree,
|
|
)
|
|
}
|
|
|
|
// Check all allocations to determine aggregate status
|
|
hasActive := false
|
|
hasJoining := false
|
|
hasLeaving := false
|
|
hasPaused := false
|
|
|
|
// Get all vertices from the hyperedge
|
|
he, ok := hyperedge.(hypergraph.Hyperedge)
|
|
if !ok {
|
|
return errors.Wrap(
|
|
errors.New("invalid object returned for hyperedge"),
|
|
"update aggregate prover status",
|
|
)
|
|
}
|
|
|
|
vertices := tries.GetAllPreloadedLeaves(he.GetExtrinsicTree().Root)
|
|
if len(vertices) > 0 {
|
|
for _, vertex := range vertices {
|
|
allocationFullAddress := vertex.Key
|
|
|
|
if !bytes.Equal(
|
|
allocationFullAddress[:32],
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS[:],
|
|
) {
|
|
return errors.Wrap(
|
|
errors.New("hyperedge includes non prover allocation vertex"),
|
|
"update aggregate prover status",
|
|
)
|
|
}
|
|
|
|
// Get allocation vertex
|
|
allocationTree, err := hg.Get(
|
|
allocationFullAddress[:32],
|
|
allocationFullAddress[32:],
|
|
hgstate.VertexAddsDiscriminator,
|
|
)
|
|
if err != nil || allocationTree == nil {
|
|
continue
|
|
}
|
|
var tree *tries.VectorCommitmentTree
|
|
var ok bool
|
|
tree, ok = allocationTree.(*tries.VectorCommitmentTree)
|
|
if !ok || tree == nil {
|
|
return errors.Wrap(
|
|
errors.New("invalid object returned for vertex"),
|
|
"update aggregate prover status",
|
|
)
|
|
}
|
|
|
|
// Check allocation status
|
|
allocStatusBytes, err := rdfMultiprover.Get(
|
|
GLOBAL_RDF_SCHEMA,
|
|
"allocation:ProverAllocation",
|
|
"Status",
|
|
tree,
|
|
)
|
|
if err == nil && len(allocStatusBytes) > 0 {
|
|
switch allocStatusBytes[0] {
|
|
case 0:
|
|
hasJoining = true
|
|
case 1:
|
|
hasActive = true
|
|
case 2:
|
|
hasPaused = true
|
|
case 3:
|
|
hasLeaving = true
|
|
// case 4 (left) is ignored for aggregate calculation
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Determine aggregate prover status based on allocation statuses
|
|
// Priority order: active > joining > leaving > paused > left
|
|
var newProverStatus byte
|
|
if hasActive {
|
|
newProverStatus = 1 // Active if any allocation is active or some are paused
|
|
} else if hasJoining {
|
|
newProverStatus = 0 // Joining if any allocation is joining
|
|
} else if hasLeaving {
|
|
newProverStatus = 3 // Leaving if any allocation is leaving
|
|
} else if hasPaused {
|
|
newProverStatus = 2 // Paused if all allocations are paused
|
|
} else {
|
|
newProverStatus = 4 // Left if all allocations are left
|
|
}
|
|
|
|
// Update prover status
|
|
err = rdfMultiprover.Set(
|
|
GLOBAL_RDF_SCHEMA,
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS[:],
|
|
"prover:Prover",
|
|
"Status",
|
|
[]byte{newProverStatus},
|
|
proverTree,
|
|
)
|
|
if err != nil {
|
|
return errors.Wrap(err, "update aggregate prover status")
|
|
}
|
|
|
|
var prior *tries.VectorCommitmentTree
|
|
existingRecord, err := hg.Get(
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS[:],
|
|
proverAddress,
|
|
hgstate.VertexAddsDiscriminator,
|
|
)
|
|
if err != nil {
|
|
prior = existingRecord.(*tries.VectorCommitmentTree)
|
|
}
|
|
|
|
// Update prover vertex
|
|
proverVertex := hg.NewVertexAddMaterializedState(
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS,
|
|
[32]byte(proverAddress),
|
|
frameNumber,
|
|
prior,
|
|
proverTree,
|
|
)
|
|
|
|
err = hg.Set(
|
|
intrinsics.GLOBAL_INTRINSIC_ADDRESS[:],
|
|
proverAddress,
|
|
hgstate.VertexAddsDiscriminator,
|
|
frameNumber,
|
|
proverVertex,
|
|
)
|
|
if err != nil {
|
|
return errors.Wrap(err, "update aggregate prover status")
|
|
}
|
|
|
|
return nil
|
|
}
|