mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
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.
150 lines
4.0 KiB
Go
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
|
|
}
|