gcx/backend/services/chain-indexer/internal/domain/entity/block.go

115 lines
3.1 KiB
Go

package entity
import (
"fmt"
"time"
)
// Block is the aggregate root representing an indexed blockchain block.
type Block struct {
Height int64 `json:"height"`
Hash string `json:"hash"`
Timestamp time.Time `json:"timestamp"`
TxCount int `json:"txCount"`
}
// NewBlock is the factory method that creates a validated Block entity.
func NewBlock(height int64, hash string, timestamp time.Time, txCount int) (*Block, error) {
if height < 0 {
return nil, fmt.Errorf("block height must be non-negative, got %d", height)
}
if hash == "" {
return nil, fmt.Errorf("block hash must not be empty")
}
if txCount < 0 {
return nil, fmt.Errorf("transaction count must be non-negative, got %d", txCount)
}
return &Block{
Height: height,
Hash: hash,
Timestamp: timestamp,
TxCount: txCount,
}, nil
}
// Validate checks all invariants on an existing Block.
func (b *Block) Validate() error {
if b.Height < 0 {
return fmt.Errorf("block height must be non-negative")
}
if b.Hash == "" {
return fmt.Errorf("block hash must not be empty")
}
if b.TxCount < 0 {
return fmt.Errorf("transaction count must be non-negative")
}
return nil
}
// IsGenesis reports whether this is the genesis block (height 0).
func (b *Block) IsGenesis() bool {
return b.Height == 0
}
// HasTransactions reports whether this block contains any transactions.
func (b *Block) HasTransactions() bool {
return b.TxCount > 0
}
// ChainTransaction represents an indexed on-chain transaction.
type ChainTransaction struct {
Hash string `json:"hash"`
BlockHeight int64 `json:"blockHeight"`
From string `json:"from"`
To string `json:"to"`
Amount string `json:"amount"`
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
}
// NewChainTransaction is the factory method that creates a validated ChainTransaction.
func NewChainTransaction(hash string, blockHeight int64, from, to, amount, status string, timestamp time.Time) (*ChainTransaction, error) {
if hash == "" {
return nil, fmt.Errorf("transaction hash must not be empty")
}
if blockHeight < 0 {
return nil, fmt.Errorf("block height must be non-negative")
}
if from == "" {
return nil, fmt.Errorf("from address must not be empty")
}
return &ChainTransaction{
Hash: hash,
BlockHeight: blockHeight,
From: from,
To: to,
Amount: amount,
Status: status,
Timestamp: timestamp,
}, nil
}
// Validate checks all invariants on an existing ChainTransaction.
func (tx *ChainTransaction) Validate() error {
if tx.Hash == "" {
return fmt.Errorf("transaction hash must not be empty")
}
if tx.BlockHeight < 0 {
return fmt.Errorf("block height must be non-negative")
}
if tx.From == "" {
return fmt.Errorf("from address must not be empty")
}
return nil
}
// IsConfirmed reports whether the transaction has a "confirmed" status.
func (tx *ChainTransaction) IsConfirmed() bool {
return tx.Status == "confirmed"
}
// IsPending reports whether the transaction has a "pending" status.
func (tx *ChainTransaction) IsPending() bool {
return tx.Status == "pending"
}