feat(consensus): scaffold package with error types

Add consensus/ package with doc.go and sentinel error types for all
validation failures. Add MaxTransactionBlobSize constant to config.

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Claude 2026-02-21 00:39:41 +00:00
parent bd8a42562a
commit fa1c127e12
No known key found for this signature in database
GPG key ID: AF404715446AEB41
6 changed files with 84 additions and 0 deletions

View file

@ -173,6 +173,11 @@ const (
// transaction blob in bytes.
CoinbaseBlobReservedSize uint64 = 1100
// MaxTransactionBlobSize is the maximum serialised transaction size in bytes.
// Derived from BlockGrantedFullRewardZone - 2*CoinbaseBlobReservedSize
// but the canonical C++ value is 374,600.
MaxTransactionBlobSize uint64 = 374_600
// BlockFutureTimeLimit is the maximum acceptable future timestamp for
// PoW blocks in seconds (2 hours).
BlockFutureTimeLimit uint64 = 60 * 60 * 2

19
consensus/doc.go Normal file
View file

@ -0,0 +1,19 @@
// 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 consensus implements Lethean blockchain validation rules.
//
// Validation is organised in three layers:
//
// - Structural: transaction size, input/output counts, key image
// uniqueness. No cryptographic operations required.
// - Economic: block reward calculation, fee extraction, balance
// checks, overflow detection.
// - Cryptographic: PoW hash verification (RandomX via CGo),
// ring signature verification, proof verification.
//
// All functions take *config.ChainConfig and a block height for
// hardfork-aware validation. The package has no dependency on chain/.
package consensus

38
consensus/errors.go Normal file
View file

@ -0,0 +1,38 @@
// 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 consensus
import "errors"
// Sentinel errors for consensus validation failures.
var (
// Transaction structural errors.
ErrTxTooLarge = errors.New("consensus: transaction too large")
ErrNoInputs = errors.New("consensus: transaction has no inputs")
ErrTooManyInputs = errors.New("consensus: transaction exceeds max inputs")
ErrInvalidInputType = errors.New("consensus: unsupported input type")
ErrNoOutputs = errors.New("consensus: transaction has no outputs")
ErrTooFewOutputs = errors.New("consensus: transaction below min outputs")
ErrTooManyOutputs = errors.New("consensus: transaction exceeds max outputs")
ErrInvalidOutput = errors.New("consensus: invalid output")
ErrDuplicateKeyImage = errors.New("consensus: duplicate key image in transaction")
ErrInvalidExtra = errors.New("consensus: invalid extra field")
// Transaction economic errors.
ErrInputOverflow = errors.New("consensus: input amount overflow")
ErrOutputOverflow = errors.New("consensus: output amount overflow")
ErrNegativeFee = errors.New("consensus: outputs exceed inputs")
// Block errors.
ErrBlockTooLarge = errors.New("consensus: block exceeds max size")
ErrTimestampFuture = errors.New("consensus: block timestamp too far in future")
ErrTimestampOld = errors.New("consensus: block timestamp below median")
ErrMinerTxInputs = errors.New("consensus: invalid miner transaction inputs")
ErrMinerTxHeight = errors.New("consensus: miner transaction height mismatch")
ErrMinerTxUnlock = errors.New("consensus: miner transaction unlock time invalid")
ErrRewardMismatch = errors.New("consensus: block reward mismatch")
ErrMinerTxProofs = errors.New("consensus: miner transaction proof count invalid")
)

16
consensus/errors_test.go Normal file
View file

@ -0,0 +1,16 @@
//go:build !integration
package consensus
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
func TestErrors_Good(t *testing.T) {
assert.True(t, errors.Is(ErrTxTooLarge, ErrTxTooLarge))
assert.False(t, errors.Is(ErrTxTooLarge, ErrNoInputs))
assert.Contains(t, ErrTxTooLarge.Error(), "too large")
}

4
go.mod
View file

@ -5,17 +5,21 @@ go 1.25.5
require (
forge.lthn.ai/core/go-p2p v0.0.0-00010101000000-000000000000
forge.lthn.ai/core/go-store v0.0.0-00010101000000-000000000000
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.48.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/sys v0.41.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.67.6 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect

2
go.sum
View file

@ -31,6 +31,8 @@ golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=