chainmigrate

package
v1.20.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2025 License: BSD-3-Clause Imports: 5 Imported by: 0

README

Chain Migration Framework

A generic blockchain import/export framework for migrating data between different blockchain implementations, enabling live mainnet "regenesis" and cross-chain state transfers.

Overview

This framework provides a flexible, extensible solution for migrating blockchain data between different chain implementations, including:

  • SubnetEVMC-Chain (with CorethVM compatibility)
  • Zoo L2C-Chain or any other chain
  • C-ChainSubnetEVM
  • Any custom blockchain that implements the interfaces

Features

  • Generic Interfaces: Clean separation between exporters and importers
  • Multiple Database Backends: Support for PebbleDB, BadgerDB, LevelDB
  • Streaming Architecture: Efficient memory usage for large chains
  • Parallel Processing: Configurable worker pools for performance
  • Progress Tracking: Real-time progress reporting with ETA
  • Error Recovery: Continue-on-error mode for resilient migrations
  • Verification: Optional block and state verification
  • CorethVM Compatibility: Special handling for C-Chain differences
  • L2 Support: Built-in support for optimistic rollups

Architecture

┌─────────────────┐     ┌──────────────┐     ┌─────────────────┐
│  Source Chain   │────▶│   Exporter   │────▶│    Migrator     │
│  (SubnetEVM)    │     │              │     │  (Orchestrator) │
└─────────────────┘     └──────────────┘     └────────┬────────┘
                                                       │
                                                       ▼
┌─────────────────┐     ┌──────────────┐     ┌─────────────────┐
│   Dest Chain    │◀────│   Importer   │◀────│   Block Data    │
│   (C-Chain)     │     │              │     │   State Data    │
└─────────────────┘     └──────────────┘     └─────────────────┘

Components

Core Interfaces
ChainExporter
type ChainExporter interface {
    Init(config ExporterConfig) error
    GetChainInfo() (*ChainInfo, error)
    ExportBlocks(ctx context.Context, start, end uint64) (<-chan *BlockData, <-chan error)
    ExportState(ctx context.Context, blockNumber uint64) (<-chan *StateAccount, <-chan error)
    ExportConfig() (*ChainConfig, error)
    VerifyExport(blockNumber uint64) error
    Close() error
}
ChainImporter
type ChainImporter interface {
    Init(config ImporterConfig) error
    ImportConfig(config *ChainConfig) error
    ImportBlock(block *BlockData) error
    ImportBlocks(blocks []*BlockData) error
    ImportState(accounts []*StateAccount, blockNumber uint64) error
    FinalizeImport(blockNumber uint64) error
    VerifyImport(blockNumber uint64) error
    ExecuteBlock(block *BlockData) error
    Close() error
}
Implementations
  • SubnetEVMExporter: Exports from SubnetEVM databases
  • CChainImporter: Imports into C-Chain with optional CorethVM compatibility
  • ZooL2Exporter: Exports from Zoo L2 via RPC
  • ChainMigrator: Orchestrates the entire migration process

Usage

Command Line Tool
# Build the tool
cd cmd/chainmigrate
go build -o chainmigrate

# Migrate SubnetEVM to C-Chain
./chainmigrate \
  --source-type=subnet-evm \
  --source-db=/path/to/subnet/db \
  --source-db-type=pebble \
  --dest-type=c-chain \
  --dest-db=/path/to/cchain/db \
  --dest-db-type=leveldb \
  --start-block=0 \
  --end-block=1074616 \
  --verify-blocks \
  --verify-state \
  --coreth-compat

# Migrate Zoo L2 to C-Chain
./chainmigrate \
  --source-type=zoo-l2 \
  --source-rpc=http://zoo-l2-rpc:8545 \
  --l1-contract=0x1234... \
  --dest-type=c-chain \
  --dest-db=/path/to/cchain/db \
  --start-block=1000000 \
  --end-block=2000000
Programmatic Usage
import "github.com/luxfi/node/chainmigrate"

// Create exporter
exporterConfig := chainmigrate.SubnetEVMExporterConfig{
    DatabasePath: "/path/to/subnet/db",
    DatabaseType: "pebble",
    Namespace:    []byte{0x33, 0x7f, ...}, // SubnetEVM namespace
}
exporter := chainmigrate.NewSubnetEVMExporter(exporterConfig)

// Create importer
importerConfig := chainmigrate.ImporterConfig{
    DatabasePath:       "/path/to/cchain/db",
    DatabaseType:       "leveldb",
    EnableCorethCompat: true,
}
importer := chainmigrate.NewCChainImporter(importerConfig)

// Create migrator
migratorConfig := chainmigrate.MigratorConfig{
    StartBlock:       0,
    EndBlock:         1074616,
    BlockBatchSize:   100,
    ParallelWorkers:  4,
    VerifyBlocks:     true,
    VerifyState:      true,
    ProgressInterval: 10 * time.Second,
}
migrator := chainmigrate.NewChainMigrator(exporter, importer, migratorConfig)

// Run migration
ctx := context.Background()
if err := migrator.Migrate(ctx); err != nil {
    log.Fatalf("Migration failed: %v", err)
}

Real-World Example: Lux Mainnet Regenesis

This framework was built to enable the migration of 1,074,617 blocks from the old Lux mainnet (network ID 96369) SubnetEVM to the new C-Chain implementation:

# Extract all blocks from SubnetEVM
./extract-all-blocks \
  --source=/path/to/lux-mainnet-96369/db/pebbledb \
  --dest=/tmp/cchain-blocks \
  --max=1074616 \
  --verify

# Migrate to C-Chain
./chainmigrate \
  --source-type=subnet-evm \
  --source-db=/tmp/cchain-blocks \
  --dest-type=c-chain \
  --dest-db=/tmp/cchain-migrated \
  --coreth-compat \
  --verify-blocks \
  --verify-state

# Start node with migrated data
LUX_IMPORTED_HEIGHT=1074616 \
CHAIN_DATA_DIR=/tmp/cchain-migrated \
luxd --network-id=96369 \
     --genesis-file=/tmp/lux-runtime-replay/genesis.json
Results
  • Blocks Migrated: 1,074,617
  • Treasury Balance: 61.5 billion LUX preserved
  • Migration Time: ~2 hours on M1 Mac
  • Database Size: ~15GB compressed
  • Verification: 100% block integrity maintained

Adding New Chain Support

To add support for a new blockchain:

  1. Create an Exporter implementing ChainExporter:
type MyChainExporter struct {
    // Your fields
}

func (e *MyChainExporter) ExportBlocks(ctx context.Context, start, end uint64) (<-chan *BlockData, <-chan error) {
    // Implementation
}
// ... implement other methods
  1. Create an Importer implementing ChainImporter:
type MyChainImporter struct {
    // Your fields
}

func (i *MyChainImporter) ImportBlock(block *BlockData) error {
    // Implementation
}
// ... implement other methods
  1. Register in CLI tool (cmd/chainmigrate/main.go):
case "my-chain":
    return NewMyChainExporter(config), nil

Performance Considerations

  • Batch Size: Default 100 blocks, adjust based on block size
  • Parallel Workers: Default 4, increase for faster migrations
  • Memory Usage: Streaming design keeps memory usage constant
  • Database Type: PebbleDB fastest for reads, LevelDB for writes
  • Network Latency: For RPC-based exports (L2), use local nodes

Testing

# Run unit tests
go test ./...

# Run integration test with test data
go test -tags=integration ./...

# Benchmark performance
go test -bench=. ./...

Limitations

  • State Migration: Only migrates state at the specified end block
  • Pruned Databases: Cannot migrate from pruned databases (need full archive)
  • Chain-Specific Features: Some features may require custom handling
  • Genesis Compatibility: Genesis must be compatible between chains

Future Enhancements

  • Incremental migration support
  • Multi-chain parallel migrations
  • State diff migration (not just end state)
  • Merkle proof verification
  • Resume from checkpoint
  • Cloud storage backend support
  • Web UI for monitoring

License

Same as Lux Node - see LICENSE file in repository root.

Support

For issues or questions, please open an issue in the Lux Node repository.

Documentation

Overview

Package chainmigrate provides generic blockchain import/export functionality for migrating data between different blockchain implementations. Supports SubnetEVM→C-Chain, Zoo L2→mainnet, and any future chain migrations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BlockData

type BlockData struct {
	// Core block data
	Number           uint64
	Hash             common.Hash
	ParentHash       common.Hash
	Timestamp        uint64
	StateRoot        common.Hash
	ReceiptsRoot     common.Hash
	TransactionsRoot common.Hash

	// Block metadata
	GasLimit        uint64
	GasUsed         uint64
	Difficulty      *big.Int
	TotalDifficulty *big.Int
	Coinbase        common.Address
	Nonce           types.BlockNonce
	MixHash         common.Hash
	ExtraData       []byte
	BaseFee         *big.Int // EIP-1559

	// Full data
	Header       []byte         // RLP encoded header
	Body         []byte         // RLP encoded body
	Receipts     []byte         // RLP encoded receipts
	Transactions []*Transaction // Decoded transactions
	UncleHeaders [][]byte       // Uncle/ommer headers

	// Chain-specific extensions
	Extensions map[string]interface{} // For chain-specific data
}

BlockData represents a generic block with all necessary data

type ChainConfig

type ChainConfig struct {
	// Network configuration
	NetworkID uint64
	ChainID   *big.Int

	// Genesis configuration
	GenesisBlock *BlockData
	GenesisAlloc map[common.Address]*StateAccount

	// Chain parameters
	HomesteadBlock      *big.Int
	EIP150Block         *big.Int
	EIP155Block         *big.Int
	EIP158Block         *big.Int
	ByzantiumBlock      *big.Int
	ConstantinopleBlock *big.Int
	PetersburgBlock     *big.Int
	IstanbulBlock       *big.Int
	BerlinBlock         *big.Int
	LondonBlock         *big.Int

	// Special configurations
	IsCoreth bool // Special handling for Coreth VM differences
	HasNetID bool
	NetID    string

	// Custom precompiles
	Precompiles map[common.Address]string
}

ChainConfig contains chain configuration

type ChainExporter

type ChainExporter interface {
	// Initialize the exporter with source database
	Init(config ExporterConfig) error

	// Get chain metadata
	GetChainInfo() (*ChainInfo, error)

	// Export blocks in a range (inclusive)
	ExportBlocks(ctx context.Context, start, end uint64) (<-chan *BlockData, <-chan error)

	// Export state at a specific block
	ExportState(ctx context.Context, blockNumber uint64) (<-chan *StateAccount, <-chan error)

	// Export specific account state
	ExportAccount(ctx context.Context, address common.Address, blockNumber uint64) (*StateAccount, error)

	// Export chain configuration (genesis, network ID, etc.)
	ExportConfig() (*ChainConfig, error)

	// Verify export integrity
	VerifyExport(blockNumber uint64) error

	// Close the exporter
	Close() error
}

ChainExporter defines the interface for exporting blockchain data

type ChainImporter

type ChainImporter interface {
	// Initialize the importer with destination database
	Init(config ImporterConfig) error

	// Import chain configuration
	ImportConfig(config *ChainConfig) error

	// Import blocks (must be sequential)
	ImportBlock(block *BlockData) error

	// Import blocks in batch
	ImportBlocks(blocks []*BlockData) error

	// Import state accounts
	ImportState(accounts []*StateAccount, blockNumber uint64) error

	// Finalize import at block height
	FinalizeImport(blockNumber uint64) error

	// Verify import integrity
	VerifyImport(blockNumber uint64) error

	// Execute block to rebuild state (for runtime replay)
	ExecuteBlock(block *BlockData) error

	// Close the importer
	Close() error
}

ChainImporter defines the interface for importing blockchain data

type ChainInfo

type ChainInfo struct {
	ChainType       ChainType
	NetworkID       uint64
	ChainID         *big.Int
	GenesisHash     common.Hash
	CurrentHeight   uint64
	TotalDifficulty *big.Int
	StateRoot       common.Hash

	// Chain-specific info
	VMVersion    string
	DatabaseType string // "pebble", "badger", "leveldb"
	IsPruned     bool
	ArchiveMode  bool

	// Special flags
	HasWarpMessages bool // For subnet communications
	HasProposerVM   bool // For proposer VM chains
}

ChainInfo contains metadata about a blockchain

type ChainMigrator

type ChainMigrator interface {
	// Migrate performs the full migration
	Migrate(ctx context.Context, source ChainExporter, dest ChainImporter, options MigrationOptions) error

	// MigrateRange migrates a specific block range
	MigrateRange(ctx context.Context, source ChainExporter, dest ChainImporter, start, end uint64) error

	// MigrateState migrates state at a specific height
	MigrateState(ctx context.Context, source ChainExporter, dest ChainImporter, blockNumber uint64) error

	// VerifyMigration verifies the migration was successful
	VerifyMigration(source ChainExporter, dest ChainImporter, blockNumber uint64) error
}

ChainMigrator orchestrates the migration between chains

type ChainType

type ChainType string

ChainType identifies the type of blockchain

const (
	ChainTypeSubnetEVM ChainType = "subnet-evm"
	ChainTypeCChain    ChainType = "c-chain"
	ChainTypeCoreth    ChainType = "coreth" // Special case for old Coreth VM
	ChainTypeZooL2     ChainType = "zoo-l2"
	ChainTypeCustom    ChainType = "custom"
	ChainTypePChain    ChainType = "p-chain"
	ChainTypeXChain    ChainType = "x-chain"
	ChainTypeQChain    ChainType = "q-chain"
)

type ExporterConfig

type ExporterConfig struct {
	ChainType    ChainType
	DatabasePath string
	DatabaseType string // "pebble", "badger", "leveldb"

	// For net chains
	NetNamespace []byte
	NetID        string

	// Export options
	ExportState     bool
	ExportReceipts  bool
	VerifyIntegrity bool
	MaxConcurrency  int

	// Special handling
	CorethCompat bool // Enable Coreth VM compatibility mode
}

ExporterConfig configures a chain exporter

type ImporterConfig

type ImporterConfig struct {
	ChainType    ChainType
	DatabasePath string
	DatabaseType string

	// Import options
	ExecuteBlocks  bool // Execute transactions vs just import data
	VerifyState    bool
	BatchSize      int
	MaxConcurrency int

	// State management
	PreserveState bool // Preserve existing state
	MergeState    bool // Merge with existing state

	// Special handling
	CorerthCompat bool
	GenesisTime   time.Time
}

ImporterConfig configures a chain importer

type MigrationOptions

type MigrationOptions struct {
	// Block range
	StartBlock uint64
	EndBlock   uint64

	// Processing options
	BatchSize       int
	MaxConcurrency  int
	VerifyEachBlock bool

	// State options
	MigrateState bool
	StateHeight  uint64 // Block height for state migration

	// Error handling
	ContinueOnError bool
	RetryFailures   int

	// Progress reporting
	ProgressCallback func(current, total uint64)

	// Special migrations
	RegenesisMode  bool                              // For mainnet regenesis
	PreserveNonces bool                              // Preserve account nonces
	RemapAddresses map[common.Address]common.Address // Address remapping
}

MigrationOptions configures the migration process

type MigrationResult

type MigrationResult struct {
	Success        bool
	BlocksMigrated uint64
	StatesMigrated uint64
	StartTime      time.Time
	EndTime        time.Time
	Errors         []error

	// Verification results
	SourceStateRoot common.Hash
	DestStateRoot   common.Hash
	StateMatches    bool
}

MigrationResult contains the result of a migration

type StateAccount

type StateAccount struct {
	Address     common.Address
	Nonce       uint64
	Balance     *big.Int
	CodeHash    common.Hash
	StorageRoot common.Hash
	Code        []byte                      // Contract code
	Storage     map[common.Hash]common.Hash // Storage slots
}

StateAccount represents an account in the state trie

type Transaction

type Transaction struct {
	Hash     common.Hash
	Nonce    uint64
	From     common.Address
	To       *common.Address // nil for contract creation
	Value    *big.Int
	Gas      uint64
	GasPrice *big.Int
	Data     []byte
	V, R, S  *big.Int // Signature values

	// EIP-1559 fields
	GasTipCap  *big.Int
	GasFeeCap  *big.Int
	AccessList types.AccessList

	// Receipt data
	Receipt *TransactionReceipt
}

Transaction represents a generic transaction

type TransactionReceipt

type TransactionReceipt struct {
	Status            uint64
	CumulativeGasUsed uint64
	Bloom             types.Bloom
	Logs              []*types.Log
	TransactionHash   common.Hash
	ContractAddress   *common.Address
	GasUsed           uint64
}

TransactionReceipt represents a transaction receipt

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL