2021-11-05 16:11:15 -04:00
package utils
import (
2021-11-12 14:26:38 -05:00
"encoding/json"
2022-04-19 10:24:55 -07:00
"errors"
2021-11-12 14:26:38 -05:00
"fmt"
2022-04-19 10:24:55 -07:00
"io/fs"
"os"
2022-06-14 14:41:45 -04:00
"time"
2021-11-05 16:11:15 -04:00
2026-01-03 07:05:17 -08:00
"github.com/luxfi/ids"
"github.com/luxfi/log"
2025-07-17 16:29:44 -05:00
rpcb "github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/node/staking"
2021-11-05 16:11:15 -04:00
)
2022-06-27 12:21:32 -03:00
const (
genesisNetworkIDKey = "networkID"
dirTimestampFormat = "20060102_150405"
)
2021-11-12 14:26:38 -05:00
2022-05-27 15:07:04 -03:00
func ToNodeID ( stakingKey , stakingCert [] byte ) ( ids . NodeID , error ) {
2022-04-17 18:33:08 -04:00
cert , err := staking . LoadTLSCertFromBytes ( stakingKey , stakingCert )
2021-11-05 16:11:15 -04:00
if err != nil {
2022-05-27 15:07:04 -03:00
return ids . EmptyNodeID , err
2021-11-05 16:11:15 -04:00
}
2025-08-06 04:56:44 +00:00
stakingCertificate := & ids . Certificate {
2025-07-18 06:49:13 +00:00
Raw : cert . Leaf . Raw ,
PublicKey : cert . Leaf . PublicKey ,
}
nodeID := ids . NodeIDFromCert ( stakingCertificate )
2022-04-17 18:33:08 -04:00
return nodeID , nil
2021-11-05 16:11:15 -04:00
}
2021-11-12 14:26:38 -05:00
// Returns the network ID in the given genesis
func NetworkIDFromGenesis ( genesis [] byte ) ( uint32 , error ) {
genesisMap := map [ string ] interface {}{}
if err := json . Unmarshal ( genesis , & genesisMap ); err != nil {
return 0 , fmt . Errorf ( "couldn't unmarshal genesis: %w" , err )
}
networkIDIntf , ok := genesisMap [ genesisNetworkIDKey ]
if ! ok {
return 0 , fmt . Errorf ( "couldn't find key %q in genesis" , genesisNetworkIDKey )
}
networkID , ok := networkIDIntf .( float64 )
if ! ok {
return 0 , fmt . Errorf ( "expected float64 but got %T" , networkIDIntf )
}
return uint32 ( networkID ), nil
}
2021-12-20 16:16:13 -05:00
2022-04-19 10:24:55 -07:00
var (
2024-01-02 20:55:14 +01:00
ErrInvalidExecPath = errors . New ( "lux exec is invalid" )
ErrNotExists = errors . New ( "lux exec not exists" )
2023-04-27 12:17:05 -03:00
ErrNotExistsPlugin = errors . New ( "plugin exec not exists" )
2022-04-19 10:24:55 -07:00
)
2022-06-02 21:55:45 -03:00
func CheckExecPath ( exec string ) error {
2022-04-19 10:24:55 -07:00
if exec == "" {
return ErrInvalidExecPath
}
_ , err := os . Stat ( exec )
if err != nil {
if errors . Is ( err , fs . ErrNotExist ) {
return ErrNotExists
}
return fmt . Errorf ( "failed to stat exec %q (%w)" , exec , err )
}
2022-06-02 21:55:45 -03:00
return nil
}
2022-04-19 10:24:55 -07:00
2023-04-27 12:17:05 -03:00
func CheckPluginPath ( pluginExec string ) error {
2022-06-02 21:55:45 -03:00
var err error
2022-04-19 10:24:55 -07:00
if _ , err = os . Stat ( pluginExec ); err != nil {
if errors . Is ( err , fs . ErrNotExist ) {
return ErrNotExistsPlugin
}
return fmt . Errorf ( "failed to stat plugin exec %q (%w)" , pluginExec , err )
}
return nil
}
func VMID ( vmName string ) ( ids . ID , error ) {
if len ( vmName ) > 32 {
return ids . Empty , fmt . Errorf ( "VM name must be <= 32 bytes, found %d" , len ( vmName ))
}
b := make ([] byte , 32 )
copy ( b , [] byte ( vmName ))
return ids . ToID ( b )
}
2022-06-14 14:41:45 -04:00
func MkDirWithTimestamp ( dirPrefix string ) ( string , error ) {
2022-06-27 12:21:32 -03:00
currentTime := time . Now (). Format ( dirTimestampFormat )
dirName := dirPrefix + "_" + currentTime
2022-06-14 14:41:45 -04:00
return dirName , os . MkdirAll ( dirName , os . ModePerm )
}
2023-04-10 11:59:50 -04:00
2025-12-19 07:11:06 -08:00
func VerifyChainHasCorrectParticipants (
2025-12-22 12:38:25 -08:00
logger log . Logger ,
2025-12-19 07:11:06 -08:00
chainParticipants [] string ,
2023-04-10 12:04:37 -04:00
cluster * rpcb . ClusterInfo ,
2025-12-19 07:11:06 -08:00
chainID string ,
2023-04-10 12:04:37 -04:00
) bool {
2023-04-10 11:59:50 -04:00
if cluster != nil {
2025-12-19 07:11:06 -08:00
participatingNodeNames := cluster . Chains [ chainID ]. GetChainParticipants (). GetNodeNames ()
2023-04-13 23:12:14 -04:00
2023-04-10 11:59:50 -04:00
var nodeIsInList bool
2025-12-19 07:11:06 -08:00
// Check that all chain validators are equal to the node IDs added as participant in chain creation
for _ , node := range chainParticipants {
2023-04-10 11:59:50 -04:00
nodeIsInList = false
2025-12-19 07:11:06 -08:00
for _ , chainValidator := range participatingNodeNames {
if chainValidator == node {
2023-04-10 11:59:50 -04:00
nodeIsInList = true
break
}
}
if ! nodeIsInList {
2025-12-22 12:38:25 -08:00
ux . Print ( logger , "%s" , log . Red . Wrap ( fmt . Sprintf ( "VerifyChainHasCorrectParticipants: %#v" , cluster )))
ux . Print ( logger , "%s" , log . Red . Wrap ( fmt . Sprintf ( "VerifyChainHasCorrectParticipants: node not in list chain %q node %q %v %v" , chainID , node , chainParticipants , participatingNodeNames )))
2023-04-10 11:59:50 -04:00
return false
}
}
return true
2023-04-21 15:00:44 -03:00
} else {
2025-12-22 12:38:25 -08:00
ux . Print ( logger , "%s" , log . Red . Wrap ( "VerifyChainHasCorrectParticipants: cluster is nil" ))
2023-04-10 11:59:50 -04:00
}
return false
}