mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
go list ./... returned nothing, so no package here could be built or tested and the failure was invisible: one directory held a Go test beside fifteen .cpp files, which makes it a Go package the toolchain then refuses. The generator moves to the golden/ subdirectory the other two C++ chains already use. That silence was hiding a package that does not compile. host/ calls EnsureIdentity and identity.go defines LoadIdentity ā a rename that happened on one side ā and it has no importers, because the Go host is cmd/luxd now. Deleted rather than repaired: the thing it was a stand-in for arrived. The operator tools came across too (backup, blscheck, ceremony, config, genesishash, keytoaddr, pqkeygen, repair-proposervm, wire) plus benchmarks and examples, so the package set now differs from the retired repo by exactly one name: main/ is cmd/luxd. Two tests were right and are now satisfied rather than silenced. The purity test looked for ./main; it looks where the daemon lives. The chain-address test found conformance/dex spelling /v1/chain by hand ā but that is its own module on purpose, since it links an EVM ABI and a signer the node must not carry, so it cannot call Chain. The rule is about this module, and the walk now says so.
261 lines
6.6 KiB
Go
261 lines
6.6 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Multi-Network Validation Proof of Concept
|
|
// This demonstrates how a single Lux Node could validate multiple networks
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/luxfi/constants"
|
|
)
|
|
|
|
// NetworkValidator represents a validator for a specific network
|
|
type NetworkValidator struct {
|
|
NetworkID uint32
|
|
NetworkName string
|
|
RPCPort int
|
|
Validators int
|
|
ChainID string
|
|
Active bool
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// MultiNetworkNode represents a node validating multiple networks
|
|
type MultiNetworkNode struct {
|
|
Networks map[uint32]*NetworkValidator
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewMultiNetworkNode creates a new multi-network node
|
|
// Network IDs: 1 (mainnet), 2 (testnet), 3 (devnet) - P-Chain identifiers
|
|
// Chain IDs: 96369, 96368, 96370 - C-Chain EVM identifiers (can be used as aliases)
|
|
func NewMultiNetworkNode() *MultiNetworkNode {
|
|
return &MultiNetworkNode{
|
|
Networks: map[uint32]*NetworkValidator{
|
|
constants.MainnetID: { // 1
|
|
NetworkID: constants.MainnetID,
|
|
NetworkName: "Lux Mainnet",
|
|
RPCPort: 9630,
|
|
Validators: 5,
|
|
ChainID: "2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM",
|
|
Active: true,
|
|
},
|
|
constants.TestnetID: { // 2
|
|
NetworkID: constants.TestnetID,
|
|
NetworkName: "Lux Testnet",
|
|
RPCPort: 9620,
|
|
Validators: 5,
|
|
ChainID: "2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm",
|
|
Active: true,
|
|
},
|
|
200200: { // Zoo chain Chain ID
|
|
NetworkID: 200200,
|
|
NetworkName: "Zoo Network",
|
|
RPCPort: 2000,
|
|
Validators: 5,
|
|
ChainID: "2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt",
|
|
Active: true,
|
|
},
|
|
// Q-Chain is part of the primary network (mainnet ID 1)
|
|
// and no longer has a separate network ID ā see the
|
|
// MainnetID entry above. The Q-Chain blockchain ID lives
|
|
// in luxfi/constants.QChainID; consumers can read it from
|
|
// the primary-network entry's chain registry rather than
|
|
// from a duplicate top-level map entry here.
|
|
},
|
|
}
|
|
}
|
|
|
|
// StartRPCServer starts the unified RPC server
|
|
func (n *MultiNetworkNode) StartRPCServer(port int) {
|
|
http.HandleFunc("/v1/crossnet/status", n.handleCrossNetStatus)
|
|
http.HandleFunc("/v1/crossnet/validators", n.handleCrossNetValidators)
|
|
http.HandleFunc("/v1/network/", n.handleNetworkSpecific)
|
|
|
|
fmt.Printf("š Multi-Network RPC Server starting on port %d\n", port)
|
|
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
|
}
|
|
|
|
// handleCrossNetStatus returns status of all networks
|
|
func (n *MultiNetworkNode) handleCrossNetStatus(w http.ResponseWriter, r *http.Request) {
|
|
n.mu.RLock()
|
|
defer n.mu.RUnlock()
|
|
|
|
response := `{
|
|
"networks": [`
|
|
|
|
first := true
|
|
for _, network := range n.Networks {
|
|
if !first {
|
|
response += ","
|
|
}
|
|
response += fmt.Sprintf(`
|
|
{
|
|
"networkID": %d,
|
|
"networkName": "%s",
|
|
"active": %t,
|
|
"validators": %d,
|
|
"chainID": "%s",
|
|
"rpcEndpoint": "http://localhost:%d"
|
|
}`,
|
|
network.NetworkID,
|
|
network.NetworkName,
|
|
network.Active,
|
|
network.Validators,
|
|
network.ChainID,
|
|
network.RPCPort,
|
|
)
|
|
first = false
|
|
}
|
|
|
|
response += `
|
|
]
|
|
}`
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(response))
|
|
}
|
|
|
|
// handleCrossNetValidators returns validators across all networks
|
|
func (n *MultiNetworkNode) handleCrossNetValidators(w http.ResponseWriter, r *http.Request) {
|
|
n.mu.RLock()
|
|
defer n.mu.RUnlock()
|
|
|
|
totalValidators := 0
|
|
for _, network := range n.Networks {
|
|
if network.Active {
|
|
totalValidators += network.Validators
|
|
}
|
|
}
|
|
|
|
response := fmt.Sprintf(`{
|
|
"totalNetworks": %d,
|
|
"totalValidators": %d,
|
|
"networks": {`,
|
|
len(n.Networks),
|
|
totalValidators,
|
|
)
|
|
|
|
first := true
|
|
for id, network := range n.Networks {
|
|
if !first {
|
|
response += ","
|
|
}
|
|
response += fmt.Sprintf(`
|
|
"%d": {
|
|
"name": "%s",
|
|
"validators": %d,
|
|
"active": %t
|
|
}`,
|
|
id,
|
|
network.NetworkName,
|
|
network.Validators,
|
|
network.Active,
|
|
)
|
|
first = false
|
|
}
|
|
|
|
response += `
|
|
}
|
|
}`
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(response))
|
|
}
|
|
|
|
// handleNetworkSpecific routes to network-specific handlers
|
|
func (n *MultiNetworkNode) handleNetworkSpecific(w http.ResponseWriter, r *http.Request) {
|
|
// Parse network ID from path: /v1/network/{networkID}/...
|
|
// This would route to the appropriate network's chain manager
|
|
|
|
response := fmt.Sprintf(`{
|
|
"message": "Network-specific routing would happen here",
|
|
"path": "%s",
|
|
"method": "%s"
|
|
}`, r.URL.Path, r.Method)
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(response))
|
|
}
|
|
|
|
// ValidateNetwork simulates validation for a specific network
|
|
func (n *MultiNetworkNode) ValidateNetwork(networkID uint32) {
|
|
network, exists := n.Networks[networkID]
|
|
if !exists {
|
|
log.Printf("Network %d not found", networkID)
|
|
return
|
|
}
|
|
|
|
log.Printf("š· Starting validation for %s (Network ID: %d)", network.NetworkName, networkID)
|
|
|
|
// In real implementation, this would:
|
|
// 1. Connect to network-specific bootstrappers
|
|
// 2. Sync network-specific blockchain data
|
|
// 3. Participate in network-specific consensus
|
|
// 4. Store data in network-specific database
|
|
|
|
for {
|
|
network.mu.RLock()
|
|
if !network.Active {
|
|
network.mu.RUnlock()
|
|
break
|
|
}
|
|
network.mu.RUnlock()
|
|
|
|
// Simulate validation work
|
|
time.Sleep(10 * time.Second)
|
|
log.Printf("ā
Validated block on %s", network.NetworkName)
|
|
}
|
|
}
|
|
|
|
// StartAllValidators starts validation for all networks
|
|
func (n *MultiNetworkNode) StartAllValidators() {
|
|
var wg sync.WaitGroup
|
|
|
|
for networkID := range n.Networks {
|
|
wg.Add(1)
|
|
go func(id uint32) {
|
|
defer wg.Done()
|
|
n.ValidateNetwork(id)
|
|
}(networkID)
|
|
}
|
|
|
|
// Don't wait - let validators run in background
|
|
go func() {
|
|
wg.Wait()
|
|
log.Println("All validators stopped")
|
|
}()
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("š Lux Multi-Network Validator POC")
|
|
fmt.Println("=====================================")
|
|
|
|
node := NewMultiNetworkNode()
|
|
|
|
// Start validation for all networks
|
|
node.StartAllValidators()
|
|
|
|
// Start unified RPC server
|
|
fmt.Println("\nš Network Status:")
|
|
for id, network := range node.Networks {
|
|
fmt.Printf(" ⢠%s (ID: %d) - %d validators\n",
|
|
network.NetworkName, id, network.Validators)
|
|
}
|
|
|
|
fmt.Println("\nš Starting Multi-Network RPC Server...")
|
|
fmt.Println(" ⢠Cross-network status: http://localhost:9650/v1/crossnet/status")
|
|
fmt.Println(" ⢠Cross-network validators: http://localhost:9650/v1/crossnet/validators")
|
|
fmt.Println(" ⢠Network-specific: http://localhost:9650/v1/network/{networkID}/...")
|
|
|
|
// This would be replaced with actual RPC server
|
|
node.StartRPCServer(9650)
|
|
}
|