2023-11-06 14:33:47 +01:00
using GethPlugin ;
using KubernetesWorkflow ;
2023-11-12 10:07:23 +01:00
using KubernetesWorkflow.Recipe ;
2023-09-08 09:39:56 +02:00
using Utils ;
2023-04-12 13:53:55 +02:00
2023-09-11 11:59:33 +02:00
namespace CodexPlugin
2023-04-12 13:53:55 +02:00
{
2023-09-13 16:06:05 +02:00
public class CodexContainerRecipe : ContainerRecipeFactory
2023-04-12 13:53:55 +02:00
{
2024-10-25 12:39:51 +02:00
private const string DefaultDockerImage =
//"codexstorage/nim-codex:0.1.7-dist-tests"; // => 20/20: 17 seconds 10/10: 3 seconds
//"codexstorage/nim-codex:sha-2a25460-dist-tests"; // PR => 20/20: 17 seconds
//"thatbenbierens/nim-codex:blockexcpr1"; // PR with revert of "Fixes issue where only wants of type block are stored in peerContext" => 20/20: 17 seconds
//"thatbenbierens/nim-codex:blockexprecreate"; // v0.1.7 with patch => 20/20: 19 seconds
//"thatbenbierens/nim-codex:blockexprecreate016"; // v0.1.6 with patch => 20/20: 19 seconds 10/10: 2 seconds
"thatbenbierens/nim-codex:blockexchprtinker7" ;
//"thatbenbierens/nim-codex:blkexc9"; // wow-fast
blocks are stored , blocks are resolved
store - stream does not continue . node too busy ? ? ?
2023-10-19 11:12:08 +02:00
public const string ApiPortTag = "codex_api_port" ;
public const string ListenPortTag = "codex_listen_port" ;
public const string MetricsPortTag = "codex_metrics_port" ;
public const string DiscoveryPortTag = "codex_discovery_port" ;
2023-04-13 14:36:17 +02:00
2023-09-04 10:08:34 +03:00
// Used by tests for time-constraint assertions.
2023-06-07 08:30:10 +02:00
public static readonly TimeSpan MaxUploadTimePerMegabyte = TimeSpan . FromSeconds ( 2.0 ) ;
public static readonly TimeSpan MaxDownloadTimePerMegabyte = TimeSpan . FromSeconds ( 2.0 ) ;
2023-08-07 15:51:44 +02:00
public override string AppName = > "codex" ;
2023-09-28 11:31:09 +02:00
public override string Image = > GetDockerImage ( ) ;
2023-09-14 15:17:30 +10:00
2023-09-28 11:31:09 +02:00
public static string DockerImageOverride { get ; set ; } = string . Empty ;
2023-04-12 13:53:55 +02:00
2023-09-13 16:06:05 +02:00
protected override void Initialize ( StartupConfig startupConfig )
2023-04-12 13:53:55 +02:00
{
2023-09-21 11:07:27 +02:00
SetResourcesRequest ( milliCPUs : 100 , memory : 100. MB ( ) ) ;
2023-11-07 09:25:51 +01:00
//SetResourceLimits(milliCPUs: 4000, memory: 12.GB());
2023-09-18 15:45:21 +02:00
2023-11-27 19:06:04 +02:00
SetSchedulingAffinity ( notIn : "false" ) ;
2023-11-23 14:50:54 +01:00
SetSystemCriticalPriority ( ) ;
2023-11-14 10:16:00 +01:00
2023-04-12 13:53:55 +02:00
var config = startupConfig . Get < CodexStartupConfig > ( ) ;
2023-10-23 11:30:54 +02:00
var apiPort = CreateApiPort ( config , ApiPortTag ) ;
AddEnvVar ( "CODEX_API_PORT" , apiPort ) ;
2023-07-04 16:04:18 +02:00
AddEnvVar ( "CODEX_API_BINDADDR" , "0.0.0.0" ) ;
2023-09-07 08:19:19 +02:00
var dataDir = $"datadir{ContainerNumber}" ;
AddEnvVar ( "CODEX_DATA_DIR" , dataDir ) ;
2023-09-07 10:37:52 +02:00
AddVolume ( $"codex/{dataDir}" , GetVolumeCapacity ( config ) ) ;
2023-09-07 08:19:19 +02:00
2023-10-23 12:33:48 +02:00
var discPort = CreateDiscoveryPort ( config ) ;
2023-10-23 11:30:54 +02:00
AddEnvVar ( "CODEX_DISC_PORT" , discPort ) ;
2023-09-14 15:04:37 +10:00
AddEnvVar ( "CODEX_LOG_LEVEL" , config . LogLevelWithTopics ( ) ) ;
2023-07-04 16:04:18 +02:00
2023-10-23 12:33:48 +02:00
if ( config . PublicTestNet ! = null )
2023-10-23 11:30:54 +02:00
{
2023-11-15 14:53:25 +01:00
// This makes the node announce itself to its public IP address.
2023-10-27 11:21:43 +02:00
AddEnvVar ( "NAT_IP_AUTO" , "false" ) ;
2023-12-11 08:38:31 +01:00
AddEnvVar ( "NAT_PUBLIC_IP_AUTO" , PublicIpService . Address ) ;
2023-10-23 11:30:54 +02:00
}
else
{
// This makes the node announce itself to its local (pod) IP address.
AddEnvVar ( "NAT_IP_AUTO" , "true" ) ;
}
2023-04-12 13:53:55 +02:00
2023-10-23 12:33:48 +02:00
var listenPort = CreateListenPort ( config ) ;
2023-07-04 16:04:18 +02:00
AddEnvVar ( "CODEX_LISTEN_ADDRS" , $"/ip4/0.0.0.0/tcp/{listenPort.Number}" ) ;
2023-04-12 13:53:55 +02:00
2023-04-24 14:09:23 +02:00
if ( ! string . IsNullOrEmpty ( config . BootstrapSpr ) )
{
2023-07-04 16:04:18 +02:00
AddEnvVar ( "CODEX_BOOTSTRAP_NODE" , config . BootstrapSpr ) ;
2023-04-24 14:09:23 +02:00
}
2023-04-12 13:53:55 +02:00
if ( config . StorageQuota ! = null )
{
2023-07-04 16:04:18 +02:00
AddEnvVar ( "CODEX_STORAGE_QUOTA" , config . StorageQuota . SizeInBytes . ToString ( ) ! ) ;
2023-04-12 13:53:55 +02:00
}
2023-06-29 16:03:45 +02:00
if ( config . BlockTTL ! = null )
{
2023-07-14 10:45:26 +02:00
AddEnvVar ( "CODEX_BLOCK_TTL" , config . BlockTTL . ToString ( ) ! ) ;
2023-06-29 16:03:45 +02:00
}
2023-08-14 15:51:03 +02:00
if ( config . BlockMaintenanceInterval ! = null )
{
AddEnvVar ( "CODEX_BLOCK_MI" , Convert . ToInt32 ( config . BlockMaintenanceInterval . Value . TotalSeconds ) . ToString ( ) ) ;
}
2023-08-14 16:37:31 +02:00
if ( config . BlockMaintenanceNumber ! = null )
{
AddEnvVar ( "CODEX_BLOCK_MN" , config . BlockMaintenanceNumber . ToString ( ) ! ) ;
}
2023-09-13 11:59:21 +02:00
if ( config . MetricsEnabled )
{
2023-10-23 11:30:54 +02:00
var metricsPort = CreateApiPort ( config , MetricsPortTag ) ;
2023-09-13 11:59:21 +02:00
AddEnvVar ( "CODEX_METRICS" , "true" ) ;
AddEnvVar ( "CODEX_METRICS_ADDRESS" , "0.0.0.0" ) ;
AddEnvVar ( "CODEX_METRICS_PORT" , metricsPort ) ;
AddPodAnnotation ( "prometheus.io/scrape" , "true" ) ;
AddPodAnnotation ( "prometheus.io/port" , metricsPort . Number . ToString ( ) ) ;
}
2023-09-11 11:59:33 +02:00
2023-09-14 15:17:30 +10:00
if ( config . SimulateProofFailures ! = null )
2023-09-14 15:02:53 +10:00
{
AddEnvVar ( "CODEX_SIMULATE_PROOF_FAILURES" , config . SimulateProofFailures . ToString ( ) ! ) ;
}
2023-09-14 15:11:04 +10:00
2023-09-19 10:24:43 +02:00
if ( config . MarketplaceConfig ! = null )
{
var mconfig = config . MarketplaceConfig ;
2023-09-19 11:51:59 +02:00
var gethStart = mconfig . GethNode . StartResult ;
2023-11-06 16:10:19 +01:00
var wsAddress = gethStart . Container . GetInternalAddress ( GethContainerRecipe . WsPortTag ) ;
2023-09-20 09:16:57 +02:00
var marketplaceAddress = mconfig . CodexContracts . Deployment . MarketplaceAddress ;
2023-09-19 10:24:43 +02:00
2023-11-06 16:10:19 +01:00
AddEnvVar ( "CODEX_ETH_PROVIDER" , $"{wsAddress.Host.Replace(" http : //", "ws://")}:{wsAddress.Port}");
2023-09-19 10:24:43 +02:00
AddEnvVar ( "CODEX_MARKETPLACE_ADDRESS" , marketplaceAddress ) ;
2024-03-26 15:35:26 +01:00
var marketplaceSetup = config . MarketplaceConfig . MarketplaceSetup ;
2023-09-19 10:24:43 +02:00
// Custom scripting in the Codex test image will write this variable to a private-key file,
// and pass the correct filename to Codex.
2024-05-24 16:11:51 +02:00
var account = marketplaceSetup . EthAccountSetup . GetNew ( ) ;
AddEnvVar ( "PRIV_KEY" , account . PrivateKey ) ;
Additional ( account ) ;
2023-09-19 10:24:43 +02:00
2024-03-13 10:18:10 +01:00
SetCommandOverride ( marketplaceSetup ) ;
if ( marketplaceSetup . IsValidator )
2023-09-19 10:24:43 +02:00
{
2023-09-14 15:04:37 +10:00
AddEnvVar ( "CODEX_VALIDATOR" , "true" ) ;
2023-09-19 10:24:43 +02:00
}
}
2023-09-13 16:06:05 +02:00
2024-06-10 10:58:50 +02:00
if ( ! string . IsNullOrEmpty ( config . NameOverride ) )
2023-09-21 11:07:27 +02:00
{
2023-09-14 15:02:53 +10:00
AddEnvVar ( "CODEX_NODENAME" , config . NameOverride ) ;
2023-04-14 10:51:35 +02:00
}
2023-04-12 13:53:55 +02:00
}
2023-06-22 14:37:37 +02:00
2024-03-13 10:18:10 +01:00
private void SetCommandOverride ( MarketplaceSetup ms )
{
2024-03-13 10:29:26 +01:00
if ( ms . IsStorageNode )
2024-03-13 10:18:10 +01:00
{
2024-03-15 12:48:25 +01:00
OverrideCommand ( "bash" , "/docker-entrypoint.sh" , "codex" , "persistence" , "prover" ) ;
2024-03-13 10:18:10 +01:00
}
2024-03-13 10:29:26 +01:00
else
2024-03-13 10:18:10 +01:00
{
2024-03-15 12:48:25 +01:00
OverrideCommand ( "bash" , "/docker-entrypoint.sh" , "codex" , "persistence" ) ;
2024-03-13 10:18:10 +01:00
}
}
2023-10-25 14:23:07 +02:00
private Port CreateApiPort ( CodexStartupConfig config , string tag )
{
if ( config . PublicTestNet = = null ) return AddExposedPort ( tag ) ;
return AddInternalPort ( tag ) ;
}
2023-10-23 12:33:48 +02:00
private Port CreateListenPort ( CodexStartupConfig config )
{
if ( config . PublicTestNet = = null ) return AddInternalPort ( ListenPortTag ) ;
return AddExposedPort ( config . PublicTestNet . PublicListenPort , ListenPortTag ) ;
}
private Port CreateDiscoveryPort ( CodexStartupConfig config )
{
2023-10-25 14:23:07 +02:00
if ( config . PublicTestNet = = null ) return AddInternalPort ( DiscoveryPortTag , PortProtocol . UDP ) ;
2023-10-23 12:33:48 +02:00
2023-10-25 14:23:07 +02:00
return AddExposedPort ( config . PublicTestNet . PublicDiscoveryPort , DiscoveryPortTag , PortProtocol . UDP ) ;
2023-10-23 12:33:48 +02:00
}
2023-09-08 09:39:56 +02:00
private ByteSize GetVolumeCapacity ( CodexStartupConfig config )
2023-09-07 10:37:52 +02:00
{
2024-06-08 10:36:23 +02:00
if ( config . StorageQuota ! = null ) return config . StorageQuota . Multiply ( 1.2 ) ;
2023-09-08 09:39:56 +02:00
// Default Codex quota: 8 Gb, using +20% to be safe.
return 8. GB ( ) . Multiply ( 1.2 ) ;
2023-09-07 10:37:52 +02:00
}
2023-07-17 11:12:14 +02:00
private string GetDockerImage ( )
{
var image = Environment . GetEnvironmentVariable ( "CODEXDOCKERIMAGE" ) ;
if ( ! string . IsNullOrEmpty ( image ) ) return image ;
2023-09-28 11:31:09 +02:00
if ( ! string . IsNullOrEmpty ( DockerImageOverride ) ) return DockerImageOverride ;
2023-07-21 09:34:37 +02:00
return DefaultDockerImage ;
2023-07-17 11:12:14 +02:00
}
2023-04-12 13:53:55 +02:00
}
}