Files
zeekayandHanzo Dev 9fb1642e1f fix: follow warp v1.24 folding UnsignedMessage into Message
This module would not build against the warp it resolves. warp v1.24 removed the
UnsignedMessage / Message split, and the rename is a rotation, not a substitution
— every name shifted one place along:

  UnsignedMessage       -> Message       (the signed subject)
  NewUnsignedMessage    -> NewMessage
  ParseUnsignedMessage  -> ParseMessage
  Message               -> Envelope      (subject + lanes)
  NewMessage            -> NewEnvelope
  ParseMessage          -> ParseEnvelope
  VerifyMessage         -> VerifyEnvelope
  .UnsignedMessage      -> .Message
  .Signature            -> .Beam

Applying it in the obvious order silently conflates the two Message meanings, so
the rewrite goes through placeholders.

The fold is a security fix upstream, not cosmetic: Message now carries the Pulsar
lineage (SourceNebulaRoot, SourceKeyEraID, SourceGeneration, HashSuiteID) inside
the signed subject. Under the old split the BLS Beam signed only the unsigned
body and that lineage was Beam-unauthenticated.

VerifyEnvelope takes the same five arguments VerifyMessage did and is documented
as the canonical classical path, so verification semantics are unchanged here.
VerifyWithOptions is the opt-in door to the Corona and ML-DSA lanes; nothing in
this module opts in, so no PQ policy is decided by this commit.

Two shape changes fall out of Envelope holding concrete lanes:
  - Beam is a BitSetSignature value, not an interface, so the signer-count
    type-assertion in the gas path is unreachable and its unknown-signature-type
    branch is gone. A parsed envelope always has a Beam to count.
  - Envelope.Bytes reports c14n failures instead of panicking, so the RPC path
    surfaces that error rather than returning a truncated message.

NewEnvelope also takes the Corona and ML-DSA cert-set lanes; the test aggregator
is Beam-only and passes nil for both.

Builds clean, go vet clean, warp + precompile + aggregator suites pass.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 19:21:10 -07:00

79 lines
3.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Defines the stateless interface for unmarshalling an arbitrary config of a precompile
package precompileconfig
import (
consensusctx "github.com/luxfi/consensus/context"
"github.com/luxfi/consensus/engine/chain/block"
"github.com/luxfi/geth/common"
"github.com/luxfi/warp"
)
// StatefulPrecompileConfig defines the interface for a stateful precompile to
// be enabled via a network upgrade.
type Config interface {
// Key returns the unique key for the stateful precompile.
Key() string
// Timestamp returns the timestamp at which this stateful precompile should be enabled.
// 1) 0 indicates that the precompile should be enabled from genesis.
// 2) n indicates that the precompile should be enabled in the first block with timestamp >= [n].
// 3) nil indicates that the precompile is never enabled.
Timestamp() *uint64
// IsDisabled returns true if this network upgrade should disable the precompile.
IsDisabled() bool
// Equal returns true if the provided argument configures the same precompile with the same parameters.
Equal(Config) bool
// Verify is called on startup and an error is treated as fatal. Configure can assume the Config has passed verification.
Verify(ChainConfig) error
}
// PredicateContext is the context passed in to the Predicater interface to verify
// a precompile predicate within a specific ProposerVM wrapper.
type PredicateContext struct {
ConsensusCtx *consensusctx.Context
// ProposerVMBlockCtx defines the ProposerVM context the predicate is verified within
ProposerVMBlockCtx *block.Context
}
// Predicater is an optional interface for StatefulPrecompileContracts to implement.
// If implemented, the predicate will be called for each predicate included in the
// access list of a transaction.
// PredicateGas will be called while calculating the IntrinsicGas of a transaction
// causing it to be dropped if the total gas goes above the tx gas limit.
// VerifyPredicate is used to populate a bit set of predicates verified prior to
// block execution, which can be accessed via the StateDB during execution.
// The bitset is stored in the block, so that historical blocks can be re-verified
// without calling VerifyPredicate.
type Predicater interface {
PredicateGas(predicateBytes []byte) (uint64, error)
VerifyPredicate(predicateContext *PredicateContext, predicateBytes []byte) error
}
type WarpMessageWriter interface {
AddMessage(unsignedMessage *warp.Message) error
}
// AcceptContext defines the context passed in to a precompileconfig's Accepter
type AcceptContext struct {
ConsensusCtx *consensusctx.Context
Warp WarpMessageWriter
}
// Accepter is an optional interface for StatefulPrecompiledContracts to implement.
// If implemented, Accept will be called for every log with the address of the precompile when the block is accepted.
// WARNING: If you are implementing a custom precompile, beware that coreth
// will not maintain backwards compatibility of this interface and your code should not
// rely on this. Designed for use only by precompiles that ship with coreth.
type Accepter interface {
Accept(acceptCtx *AcceptContext, blockHash common.Hash, blockNumber uint64, txHash common.Hash, logIndex int, topics []common.Hash, logData []byte) error
}
// ChainConfig is the chain-configuration view available to stateful
// precompiles. Under activate-all-implicitly there are no per-upgrade gates
// left to ask about, so the interface is currently empty. A precompile that
// needs to discriminate runtime behaviour should declare its own typed input,
// not piggy-back on the chain config.
type ChainConfig interface{}