Skip to content

TX Validator Service Reference Documentation

Overview

The TX Validator Service is responsible for validating transactions in a Bitcoin SV blockchain system. It ensures that transactions conform to the network's consensus rules and policy requirements before they are added to the blockchain. The service provides both gRPC and HTTP endpoints for transaction validation and integrates with block assembly for mining operations.

The validator package implements comprehensive transaction validation functionality for Bitcoin SV nodes, including script verification, UTXO management, and policy enforcement. It is a critical component of the Teranode architecture that handles transaction validation according to Bitcoin SV consensus rules, manages UTXO state transitions, and ensures that only valid transactions are accepted into the mempool and blocks.

Core Components

Server

The Server struct is the main component of the TX Validator Service. It acts as the primary coordinator for transaction validation requests, integrating with multiple components (UTXO store, blockchain, Kafka) to provide a complete validation service.

type Server struct {
    validator_api.UnsafeValidatorAPIServer
    validator                     Interface
    logger                        ulogger.Logger
    settings                      *settings.Settings
    utxoStore                     utxo.Store
    kafkaSignal                   chan os.Signal
    stats                         *gocore.Stat
    ctx                           context.Context
    blockchainClient              blockchain.ClientI
    consumerClient                kafka.KafkaConsumerGroupI
    txMetaKafkaProducerClient     kafka.KafkaAsyncProducerI
    rejectedTxKafkaProducerClient kafka.KafkaAsyncProducerI
    blockAssemblyClient           blockassembly.ClientI
    httpServer                    *echo.Echo
}

Constructor

func NewServer(
    logger ulogger.Logger,
    tSettings *settings.Settings,
    utxoStore utxo.Store,
    blockchainClient blockchain.ClientI,
    consumerClient kafka.KafkaConsumerGroupI,
    txMetaKafkaProducerClient kafka.KafkaAsyncProducerI,
    rejectedTxKafkaProducerClient kafka.KafkaAsyncProducerI,
    blockAssemblyClient blockassembly.ClientI,
) *Server

Creates and initializes a new validator server instance with the specified components. This function initializes Prometheus metrics and configures the server with all required dependencies for transaction validation. It does not start any background processes or establish connections - that happens in the Init and Start methods.

Methods

gRPC Endpoints
  • Health(ctx context.Context, checkLiveness bool) (int, string, error): Performs health checks on the validator service and its dependencies. When used as a liveness check (checkLiveness=true), it only verifies basic service operation. When used as a readiness check (checkLiveness=false), it performs comprehensive dependency checks.
  • HealthGRPC(ctx context.Context, _ *validator_api.EmptyMessage) (*validator_api.HealthResponse, error): Implements the gRPC health check endpoint. This method provides the gRPC interface for health checking and records metrics for monitoring purposes.
  • ValidateTransaction(ctx context.Context, req *validator_api.ValidateTransactionRequest) (*validator_api.ValidateTransactionResponse, error): Validates a single transaction. This method is part of the validator_api.ValidatorAPIServer interface and serves as the public API entry point for transaction validation requests.
  • ValidateTransactionBatch(ctx context.Context, req *validator_api.ValidateTransactionBatchRequest) (*validator_api.ValidateTransactionBatchResponse, error): Validates a batch of transactions. This method provides significant performance optimization over individual validation by processing multiple transactions in parallel using Go's errgroup.
  • GetBlockHeight(ctx context.Context, _ *validator_api.EmptyMessage) (*validator_api.GetBlockHeightResponse, error): Returns the current block height. This method provides a critical service for clients needing to know the current chain state.
  • GetMedianBlockTime(ctx context.Context, _ *validator_api.EmptyMessage) (*validator_api.GetMedianBlockTimeResponse, error): Returns the median time of recent blocks. This method provides access to the median timestamp of the last several blocks, which is critical for time-based transaction features like nLockTime.
HTTP Endpoints
  • handleSingleTx(ctx context.Context) echo.HandlerFunc: Handles HTTP requests for single transaction validation. This method implements an HTTP handler for validating a single Bitcoin transaction submitted via POST request.
  • handleMultipleTx(ctx context.Context) echo.HandlerFunc: Handles HTTP requests for validating multiple transactions. This method implements an HTTP handler for validating a stream of Bitcoin transactions submitted via POST request.
  • startHTTPServer(ctx context.Context, httpAddresses string) error: Initializes and starts the HTTP server for transaction processing. This method configures and launches an Echo web server that provides HTTP REST endpoints for transaction validation.
  • startAndMonitorHTTPServer(ctx context.Context, httpAddresses string): Starts the HTTP server and monitors for shutdown. This method launches the HTTP server in a non-blocking manner using goroutines, allowing the main server thread to continue execution.
Lifecycle Methods
  • Init(ctx context.Context) error: Initializes the validator server and sets up the core validation engine. This method must be called before Start() and after NewServer(). It creates the core validator component and performs necessary setup operations.
  • Start(ctx context.Context, readyCh chan<- struct{}) error: Begins the validator server operation and registers handlers for validation requests. This method initiates all background processing, including Kafka consumer setup, HTTP API servers, and synchronization with the blockchain FSM.
  • Stop(_ context.Context) error: Gracefully shuts down the validator server and all associated components. This method performs an orderly shutdown of all server resources, including Kafka producers/consumers and any background tasks.

Validator

The Validator struct implements Bitcoin SV transaction validation and manages the lifecycle of transactions from validation through block assembly.

type Validator struct {
    logger                        ulogger.Logger
    settings                      *settings.Settings
    txValidator                   TxValidatorI
    utxoStore                     utxo.Store
    blockAssembler                blockassembly.Store
    saveInParallel                bool
    stats                         *gocore.Stat
    txmetaKafkaProducerClient     kafka.KafkaAsyncProducerI
    rejectedTxKafkaProducerClient kafka.KafkaAsyncProducerI
}

Constructor

func New(ctx context.Context, logger ulogger.Logger, tSettings *settings.Settings, store utxo.Store,
    txMetaKafkaProducerClient kafka.KafkaAsyncProducerI,
    rejectedTxKafkaProducerClient kafka.KafkaAsyncProducerI,
    blockAssemblyClient blockassembly.ClientI) (Interface, error)

Creates a new Validator instance with the provided configuration. It initializes the validator with the given logger, UTXO store, and Kafka producers. Returns an error if initialization fails.

Methods

  • Health(ctx context.Context, checkLiveness bool) (int, string, error): Performs health checks on the validator and its dependencies. When checkLiveness is true, only checks service liveness. When false, performs full readiness check including dependencies.
  • GetBlockHeight() uint32: Returns the current block height from the UTXO store.
  • GetMedianBlockTime() uint32: Returns the median block time from the UTXO store.
  • Validate(ctx context.Context, tx *bt.Tx, blockHeight uint32, opts ...Option) (*meta.Data, error): Performs comprehensive validation of a transaction. It checks transaction finality, validates inputs and outputs, updates the UTXO set, and optionally adds the transaction to block assembly.
  • ValidateWithOptions(ctx context.Context, tx *bt.Tx, blockHeight uint32, validationOptions *Options) (*meta.Data, error): Performs comprehensive validation of a transaction with explicit options. This method is the core transaction validation entry point that implements the full Bitcoin validation ruleset.
  • TriggerBatcher(): Triggers the batcher (currently a no-op).
  • CreateInUtxoStore(traceSpan tracing.Span, tx *bt.Tx, blockHeight uint32, markAsConflicting bool, markAsUnspendable bool) (*meta.Data, error): Stores transaction metadata in the UTXO store. Returns transaction metadata and error if storage fails.

TxValidator

The TxValidator implements transaction validation logic based on Bitcoin SV consensus rules and configurable policy settings.

type TxValidator struct {
    logger      ulogger.Logger
    settings    *settings.Settings
    interpreter TxScriptInterpreter
    options     *TxValidatorOptions
}

The validator package defines multiple interfaces for transaction validation:

TxValidatorI Interface

type TxValidatorI interface {
    // ValidateTransaction performs comprehensive validation of a transaction.
    // This method enforces all consensus and policy rules against the transaction,
    // including format, structure, inputs/outputs, signature verification, and fees.
    ValidateTransaction(tx *bt.Tx, blockHeight uint32, validationOptions *Options) error

    // ValidateTransactionScripts performs script validation for a transaction.
    // This method specifically handles the script execution and signature verification
    // portion of validation, which is typically the most computationally intensive part.
    ValidateTransactionScripts(tx *bt.Tx, blockHeight uint32, utxoHeights []uint32, validationOptions *Options) error
}

TxScriptInterpreter Interface

type TxScriptInterpreter interface {
    // VerifyScript implements script verification for a transaction
    VerifyScript(tx *bt.Tx, blockHeight uint32, consensus bool, utxoHeights []uint32) error

    // Interpreter returns the interpreter being used
    Interpreter() TxInterpreter
}

The validator supports multiple script interpreters through a factory pattern:

  • GoBT: Pure Go implementation from the libsv/go-bt library
  • GoSDK: Bitcoin SV SDK implementation
  • GoBDK: Bitcoin Development Kit implementation

Key Functions

TxValidator Methods

  • ValidateTransaction(tx *bt.Tx, blockHeight uint32, validationOptions *Options) error: Performs comprehensive validation checks on a transaction. This includes checking input and output presence, transaction size limits, input values and coinbase restrictions, output values and dust limits, lock time requirements, script operation limits, script validation, and fee requirements.
  • ValidateTransactionScripts(tx *bt.Tx, blockHeight uint32, utxoHeights []uint32, validationOptions *Options) error: Validates transaction scripts using the configured script interpreter.
  • checkOutputs(tx *bt.Tx, blockHeight uint32) error: Validates transaction outputs, checking for dust values and other output-specific rules.
  • checkInputs(tx *bt.Tx, blockHeight uint32) error: Validates transaction inputs, checking for proper formatting and sequence values.
  • checkTxSize(txSize int) error: Checks if the transaction size is within the allowed policy limit.
  • checkFees(tx *bt.Tx, feeQuote *bt.FeeQuote) error: Verifies if the transaction fee is sufficient according to the fee policy.
  • sigOpsCheck(tx *bt.Tx, validationOptions *Options) error: Checks the number of signature operations in the transaction against policy limits.
  • pushDataCheck(tx *bt.Tx) error: Ensures that unlocking scripts only push data onto the stack, enforcing Bitcoin's signature script policy.

Validator Methods

  • validateInternal(ctx context.Context, tx *bt.Tx, blockHeight uint32, validationOptions *Options) (txMetaData *meta.Data, err error): Performs the core validation logic for a transaction. This method contains the detailed step-by-step transaction validation workflow and manages the entire lifecycle of a transaction from initial validation through UTXO updates and optional block assembly integration.
  • validateTransaction(ctx context.Context, tx *bt.Tx, blockHeight uint32, validationOptions *Options) error: Performs transaction-level validation checks. Ensures transaction is properly extended and meets all validation rules.
  • validateTransactionScripts(ctx context.Context, tx *bt.Tx, blockHeight uint32, utxoHeights []uint32, validationOptions *Options) error: Performs script validation for a transaction. Returns error if validation fails.
  • spendUtxos(traceSpan tracing.Span, tx *bt.Tx, ignoreUnspendable bool) ([]*utxo.Spend, error): Attempts to spend the UTXOs referenced by transaction inputs. Returns the spent UTXOs and error if spending fails.
  • sendToBlockAssembler(traceSpan tracing.Span, bData *blockassembly.Data, reservedUtxos []*utxo.Spend) error: Sends validated transaction data to the block assembler. Returns error if block assembly integration fails.
  • extendTransaction(ctx context.Context, tx *bt.Tx) error: Adds previous output information to transaction inputs. Returns error if required parent transaction data cannot be found.

Configuration

The TX Validator Service uses various configuration options, including:

  • Kafka settings: Configuration for Kafka producers and consumers used in transaction processing
  • Policy settings: Transaction validation policy parameters, including fee rates, size limits, and other enforcement rules
  • Network parameters: Mainnet, testnet, or regtest configuration affecting consensus rules
  • Block assembly settings: Configuration for integrating validation with block template generation
  • Script interpreter selection: Choice of script validation engine (GoBT, GoSDK, GoBDK)

Error Handling

The service uses custom error types defined in the errors package to provide detailed information about validation failures:

  • TxInvalidError: Indicates that a transaction failed validation rules
  • ScriptVerifyError: Specific to script verification failures
  • ProcessingError: General processing errors not directly related to transaction validity
  • StorageError: Errors related to UTXO storage operations
  • ConfigurationError: Errors in service configuration

Metrics

Prometheus metrics are used to monitor various aspects of the validation process, including:

  • Transaction validation time (histogram)
  • Number of invalid transactions (counter)
  • Transaction size distribution (histogram)
  • Script verification time (histogram)
  • Fee rate distribution (histogram)
  • Number of transactions processed (counter)
  • Number of UTXOs created/spent (counter)

Kafka Integration

The service integrates with Kafka for:

  • Consuming transactions to be validated from other services
  • Producing metadata for validated transactions for downstream consumers
  • Producing information about rejected transactions for monitoring and analysis
  • Supporting asynchronous processing for high throughput