Files
node/vms/proposervm/state_syncable_vm.go
zeekay 7cf87b230b node-unified is the node
The module already called itself github.com/luxfi/node while containing no node
in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and
the Go column of the matrix measured a VM plugin. A repo that fetches the thing
it claims to be has not replaced it, so the Go sources move in — 1515 files,
the daemon and everything under it — and the build reaches outside this module
for nothing.

Rust and C++ sit beside it unchanged and are still measured against it by the
differential. That is the point of one repo: the reference implementation and
the two ports are the same checkout, so parity is a thing you can run rather
than a thing you assert.

Verified: builds, and the closure carries no lux-private — checked at build time
rather than believed. The daemon starts twelve chains on a local network
(P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
2026-09-07 16:15:25 -07:00

150 lines
4.0 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package proposervm
import (
"context"
"fmt"
"github.com/luxfi/log"
"github.com/luxfi/database"
"github.com/luxfi/node/vms/proposervm/summary"
chain "github.com/luxfi/vm/chain"
)
func (vm *VM) StateSyncEnabled(ctx context.Context) (bool, error) {
if vm.ssVM == nil {
return false, nil
}
return vm.ssVM.StateSyncEnabled(ctx)
}
func (vm *VM) GetOngoingSyncStateSummary(ctx context.Context) (chain.StateSummary, error) {
if vm.ssVM == nil {
return nil, chain.ErrStateSyncableVMNotImplemented
}
innerSummary, err := vm.ssVM.GetOngoingSyncStateSummary(ctx)
if err != nil {
return nil, err // includes database.ErrNotFound case
}
return vm.buildStateSummary(ctx, innerSummary)
}
func (vm *VM) GetLastStateSummary(ctx context.Context) (chain.StateSummary, error) {
if vm.ssVM == nil {
return nil, chain.ErrStateSyncableVMNotImplemented
}
// Extract inner vm's last state summary
innerSummary, err := vm.ssVM.GetLastStateSummary(ctx)
if err != nil {
return nil, err // including database.ErrNotFound case
}
return vm.buildStateSummary(ctx, innerSummary)
}
// Note: it's important that ParseStateSummary do not use any index or state
// to allow summaries being parsed also by freshly started node with no previous state.
func (vm *VM) ParseStateSummary(ctx context.Context, summaryBytes []byte) (chain.StateSummary, error) {
if vm.ssVM == nil {
return nil, chain.ErrStateSyncableVMNotImplemented
}
statelessSummary, err := summary.Parse(summaryBytes)
if err != nil {
// it may be a preFork summary
return vm.ssVM.ParseStateSummary(ctx, summaryBytes)
}
innerSummary, err := vm.ssVM.ParseStateSummary(ctx, statelessSummary.InnerSummaryBytes())
if err != nil {
return nil, fmt.Errorf("could not parse inner summary due to: %w", err)
}
block, err := vm.parsePostForkBlock(ctx, statelessSummary.BlockBytes(), true)
if err != nil {
return nil, fmt.Errorf("could not parse proposervm block bytes from summary due to: %w", err)
}
return &stateSummary{
StateSummary: statelessSummary,
innerSummary: innerSummary,
block: block,
vm: vm,
}, nil
}
func (vm *VM) GetStateSummary(ctx context.Context, height uint64) (chain.StateSummary, error) {
if vm.ssVM == nil {
return nil, chain.ErrStateSyncableVMNotImplemented
}
innerSummary, err := vm.ssVM.GetStateSummary(ctx, height)
if err != nil {
return nil, err // including database.ErrNotFound case
}
return vm.buildStateSummary(ctx, innerSummary)
}
// Note: building state summary requires a well formed height index.
func (vm *VM) buildStateSummary(ctx context.Context, innerSummary chain.StateSummary) (chain.StateSummary, error) {
forkHeight, err := vm.GetForkHeight()
switch err {
case nil:
if innerSummary.Height() < forkHeight {
return innerSummary, nil
}
case database.ErrNotFound:
// fork has not been reached since there is not fork height
// just return innerSummary
vm.logger.Debug("built pre-fork summary",
log.Stringer("summaryID", innerSummary.ID()),
log.Uint64("summaryHeight", innerSummary.Height()),
)
return innerSummary, nil
default:
return nil, err
}
height := innerSummary.Height()
blkID, err := vm.GetBlockIDAtHeight(ctx, height)
if err != nil {
vm.logger.Debug("failed to fetch proposervm block ID",
log.Uint64("height", height),
log.Err(err),
)
return nil, err
}
block, err := vm.getPostForkBlock(ctx, blkID)
if err != nil {
vm.logger.Warn("failed to fetch proposervm block",
log.Stringer("blkID", blkID),
log.Uint64("height", height),
log.Err(err),
)
return nil, err
}
statelessSummary, err := summary.Build(forkHeight, block.Bytes(), innerSummary.Bytes())
if err != nil {
return nil, err
}
vm.logger.Debug("built post-fork summary",
log.Stringer("summaryID", statelessSummary.ID()),
log.Uint64("summaryHeight", forkHeight),
)
return &stateSummary{
StateSummary: statelessSummary,
innerSummary: innerSummary,
block: block,
vm: vm,
}, nil
}