go-blockchain/chain/difficulty.go
Claude d456b8be9b
feat(chain): add NextDifficulty for local LWMA computation
Reads stored block timestamps and cumulative difficulties, calls
difficulty.NextDifficulty() with config.BlockTarget. Returns uint64.

Adds getBlockMeta() for lightweight metadata-only lookups.

Co-Authored-By: Charon <charon@lethean.io>
2026-02-21 22:03:28 +00:00

48 lines
1.2 KiB
Go

// Copyright (c) 2017-2026 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// SPDX-License-Identifier: EUPL-1.2
package chain
import (
"math/big"
"forge.lthn.ai/core/go-blockchain/config"
"forge.lthn.ai/core/go-blockchain/difficulty"
)
// NextDifficulty computes the expected difficulty for the block at the given
// height, using the LWMA algorithm over stored block history.
func (c *Chain) NextDifficulty(height uint64) (uint64, error) {
if height == 0 {
return 1, nil
}
// Determine how far back to look.
lookback := height
if lookback > difficulty.BlocksCount {
lookback = difficulty.BlocksCount
}
startHeight := height - lookback
count := int(lookback)
timestamps := make([]uint64, count)
cumulDiffs := make([]*big.Int, count)
for i := 0; i < count; i++ {
meta, err := c.getBlockMeta(startHeight + uint64(i))
if err != nil {
// Fewer blocks than expected — use what we have.
timestamps = timestamps[:i]
cumulDiffs = cumulDiffs[:i]
break
}
timestamps[i] = meta.Timestamp
cumulDiffs[i] = new(big.Int).SetUint64(meta.CumulativeDiff)
}
result := difficulty.NextDifficulty(timestamps, cumulDiffs, config.BlockTarget)
return result.Uint64(), nil
}