Skip to content

Commit

Permalink
Merge pull request #2319 from area363/release/72-to-main
Browse files Browse the repository at this point in the history
Release/72 to main
  • Loading branch information
area363 authored Nov 21, 2023
2 parents 9e1120b + a5b9ae9 commit 1045728
Show file tree
Hide file tree
Showing 37 changed files with 1,001 additions and 116 deletions.
2 changes: 1 addition & 1 deletion Lib9c
Submodule Lib9c updated 460 files
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ public void Mine(bool tablePathExist, bool goldDistributionExist, bool exc)
};
config["admin"] = adminConfig;

// ExtraConfig: pendingActivationStatePath

// Serialize and write config file
string json = JsonSerializer.Serialize(config);
var configPath = Path.GetTempFileName();
Expand Down
172 changes: 110 additions & 62 deletions NineChronicles.Headless.Executable/Commands/GenesisCommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text.Json;
using Bencodex;
using Bencodex.Types;
using Cocona;
using Lib9c;
using Libplanet.Common;
Expand All @@ -24,7 +23,6 @@ namespace NineChronicles.Headless.Executable.Commands
public class GenesisCommand : CoconaLiteConsoleAppBase
{
private const int DefaultCurrencyValue = 10000;
private static readonly Codec _codec = new Codec();
private readonly IConsole _console;

public GenesisCommand(IConsole console)
Expand All @@ -45,6 +43,7 @@ private void ProcessData(DataConfig config, out Dictionary<string, string> table

private void ProcessCurrency(
CurrencyConfig? config,
out Currency currency,
out PrivateKey initialMinter,
out List<GoldDistribution> initialDepositList
)
Expand All @@ -58,10 +57,17 @@ out List<GoldDistribution> initialDepositList
{
new()
{
Address = initialMinter.ToAddress(), AmountPerBlock = DefaultCurrencyValue,
StartBlock = 0, EndBlock = 0
Address = initialMinter.ToAddress(),
AmountPerBlock = DefaultCurrencyValue,
StartBlock = 0,
EndBlock = 0,
}
};

#pragma warning disable CS0618
// Use of obsolete method Currency.Legacy(): https://github.com/planetarium/lib9c/discussions/1319
currency = Currency.Legacy("NCG", 2, minters: null);
#pragma warning restore CS0618
return;
}

Expand Down Expand Up @@ -92,15 +98,24 @@ out List<GoldDistribution> initialDepositList
{
initialDepositList = config.Value.InitialCurrencyDeposit;
}

#pragma warning disable CS0618
// Use of obsolete method Currency.Legacy(): https://github.com/planetarium/lib9c/discussions/1319
currency = Currency.Legacy("NCG", 2, minters: config.Value.AllowMint ? null : ImmutableHashSet.Create(initialMinter.ToAddress()));
#pragma warning restore CS0618
}

private void ProcessAdmin(AdminConfig? config, PrivateKey initialMinter,
out AdminState adminState, out List<ActionBase> meadActions)
private void ProcessAdmin(
AdminConfig? config,
PrivateKey initialMinter,
out AdminState? adminState,
out List<ActionBase> meadActions
)
{
// FIXME: If the `adminState` is not required inside `MineGenesisBlock`,
// this logic will be much lighter.
_console.Out.WriteLine("\nProcessing admin for genesis...");
adminState = new AdminState(new Address(), 0);
adminState = default;
meadActions = new List<ActionBase>();

if (config is null)
Expand All @@ -111,31 +126,26 @@ private void ProcessAdmin(AdminConfig? config, PrivateKey initialMinter,

if (config.Value.Activate)
{
Address adminAddress;
if (string.IsNullOrEmpty(config.Value.Address))
{
_console.Out.WriteLine("Admin address not provided. Give admin privilege to initialMinter");
adminState = new AdminState(initialMinter.ToAddress(), config.Value.ValidUntil);
meadActions.Add(new PrepareRewardAssets
{
RewardPoolAddress = initialMinter.ToAddress(),
Assets = new List<FungibleAssetValue>
{
10000 * Currencies.Mead,
},
});
adminAddress = initialMinter.ToAddress();
}
else
{
adminState = new AdminState(new Address(config.Value.Address), config.Value.ValidUntil);
meadActions.Add(new PrepareRewardAssets
{
RewardPoolAddress = new Address(config.Value.Address),
Assets = new List<FungibleAssetValue>
{
10000 * Currencies.Mead,
},
});
adminAddress = new Address(config.Value.Address);
}

adminState = new AdminState(adminAddress, config.Value.ValidUntil);
meadActions.Add(new PrepareRewardAssets
{
RewardPoolAddress = adminAddress,
Assets = new List<FungibleAssetValue>
{
10000 * Currencies.Mead,
},
});
}
else
{
Expand Down Expand Up @@ -172,28 +182,57 @@ private void ProcessValidator(List<Validator>? config, PrivateKey initialValidat
_console.Out.WriteLine($"Initial validator set config done: {str}");
}

private void ProcessExtra(ExtraConfig? config,
out List<PendingActivationState> pendingActivationStates
private void ProcessInitialMeadConfigs(
List<MeadConfig>? configs,
out List<PrepareRewardAssets> meadActions
)
{
_console.Out.WriteLine("\nProcessing extra data for genesis...");
pendingActivationStates = new List<PendingActivationState>();
_console.Out.WriteLine("\nProcessing initial mead distribution...");

if (config is null)
meadActions = new List<PrepareRewardAssets>();
if (configs is { })
{
_console.Out.WriteLine("Extra config not provided");
return;
foreach (MeadConfig config in configs)
{
_console.Out.WriteLine($"Preparing initial {config.Amount} MEAD for {config.Address}...");
Address target = new(config.Address);
meadActions.Add(
new PrepareRewardAssets(
target,
new List<FungibleAssetValue>
{
FungibleAssetValue.Parse(Currencies.Mead, config.Amount),
}
)
);
}
}
}

if (!string.IsNullOrEmpty(config.Value.PendingActivationStatePath))
private void ProcessInitialPledgeConfigs(
List<PledgeConfig>? configs,
out List<CreatePledge> pledgeActions
)
{
_console.Out.WriteLine("\nProcessing initial pledges...");

pledgeActions = new List<CreatePledge>();
if (configs is { })
{
string hex = File.ReadAllText(config.Value.PendingActivationStatePath).Trim();
List decoded = (List)_codec.Decode(ByteUtil.ParseHex(hex));
CreatePendingActivations action = new();
action.LoadPlainValue(decoded[1]);
pendingActivationStates = action.PendingActivations.Select(
pa => new PendingActivationState(pa.Nonce, new PublicKey(pa.PublicKey))
).ToList();
foreach (PledgeConfig config in configs)
{
_console.Out.WriteLine($"Preparing a pledge for {config.AgentAddress}...");
Address agentAddress = new(config.AgentAddress);
Address pledgeAddress = agentAddress.GetPledgeAddress();
pledgeActions.Add(
new CreatePledge()
{
AgentAddresses = new[] { (agentAddress, pledgeAddress) },
PatronAddress = new(config.PatronAddress),
Mead = config.Mead,
}
);
}
}
}

Expand All @@ -214,26 +253,30 @@ public void Mine(
{
ProcessData(genesisConfig.Data, out var tableSheets);

ProcessCurrency(genesisConfig.Currency, out var initialMinter, out var initialDepositList);
ProcessCurrency(genesisConfig.Currency, out var currency, out var initialMinter, out var initialDepositList);

ProcessAdmin(genesisConfig.Admin, initialMinter, out var adminState, out var meadActions);
ProcessAdmin(genesisConfig.Admin, initialMinter, out var adminState, out var adminMeads);

ProcessValidator(genesisConfig.InitialValidatorSet, initialMinter, out var initialValidatorSet);

ProcessExtra(genesisConfig.Extra, out var pendingActivationStates);
ProcessInitialMeadConfigs(genesisConfig.InitialMeadConfigs, out var initialMeads);

ProcessInitialPledgeConfigs(genesisConfig.InitialPledgeConfigs, out var initialPledges);

// Mine genesis block
_console.Out.WriteLine("\nMining genesis block...\n");
Block block = BlockHelper.ProposeGenesisBlock(
tableSheets: tableSheets,
goldDistributions: initialDepositList.ToArray(),
pendingActivationStates: pendingActivationStates.ToArray(),
adminState: adminState,
pendingActivationStates: Array.Empty<PendingActivationState>(),
// FIXME Should remove default value after fixing parameter type on Lib9c side.
adminState: adminState ?? new AdminState(default, 0L),
privateKey: initialMinter,
initialValidators: initialValidatorSet.ToDictionary(
item => new PublicKey(ByteUtil.ParseHex(item.PublicKey)),
item => new BigInteger(item.Power)),
actionBases: meadActions
actionBases: adminMeads.Concat(initialMeads).Concat(initialPledges),
goldCurrency: currency
);

Lib9cUtils.ExportBlock(block, "genesis-block");
Expand Down Expand Up @@ -309,6 +352,8 @@ private struct CurrencyConfig
/// You can see newly created deposition info in <c>initial_deposit.csv</c> file.
/// </value>
public List<GoldDistribution>? InitialCurrencyDeposit { get; set; }

public bool AllowMint { get; set; }
}

/// <summary>
Expand Down Expand Up @@ -342,18 +387,22 @@ private struct Validator
public long Power { get; set; }
}

/// <summary>
/// Extra configurations.
/// </summary>
[Serializable]
private struct ExtraConfig
private struct MeadConfig
{
/// <value>
/// Dump file path of pending activation state created using <c>9c-tools</c><br/>
/// This will set activation codes that can be used to genesis block. <br/>
/// See <see cref="TxCommand"/> to create activation key.
/// </value>
public string? PendingActivationStatePath { get; set; }
public string Address { get; set; }

public string Amount { get; set; }
}

[Serializable]
private struct PledgeConfig
{
public string AgentAddress { get; set; }

public string PatronAddress { get; set; }

public int Mead { get; set; }
}

/// <summary>
Expand All @@ -380,10 +429,6 @@ private struct ExtraConfig
/// <term><see cref="InitialValidatorSet">Initial validator set</see></term>
/// <description>Optional. Sets game admin and lifespan to genesis block.</description>
/// </item>
/// <item>
/// <term><see cref="ExtraConfig">Extra</see></term>
/// <description>Optional. Sets extra data (e.g. activation keys) to genesis block.</description>
/// </item>
/// </list>
[Serializable]
private struct GenesisConfig
Expand All @@ -392,7 +437,10 @@ private struct GenesisConfig
public CurrencyConfig? Currency { get; set; }
public AdminConfig? Admin { get; set; }
public List<Validator>? InitialValidatorSet { get; set; }
public ExtraConfig? Extra { get; set; }

public List<MeadConfig>? InitialMeadConfigs { get; set; }

public List<PledgeConfig>? InitialPledgeConfigs { get; set; }
}
#pragma warning restore S3459
}
Expand Down
6 changes: 5 additions & 1 deletion NineChronicles.Headless.Executable/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public class Configuration

public AccessControlServiceOptions? AccessControlService { get; set; }

public int ArenaParticipantsSyncInterval { get; set; } = 1000;

public void Overwrite(
string? appProtocolVersionString,
string[]? trustedAppProtocolVersionSignerStrings,
Expand Down Expand Up @@ -138,7 +140,8 @@ public void Overwrite(
string[]? consensusSeedStrings,
double? consensusTargetBlockIntervalMilliseconds,
string? sentryDsn,
double? sentryTraceSampleRate
double? sentryTraceSampleRate,
int? arenaParticipantsSyncInterval
)
{
AppProtocolVersionString = appProtocolVersionString ?? AppProtocolVersionString;
Expand Down Expand Up @@ -189,6 +192,7 @@ public void Overwrite(
ConsensusTargetBlockIntervalMilliseconds = consensusTargetBlockIntervalMilliseconds ?? ConsensusTargetBlockIntervalMilliseconds;
SentryDsn = sentryDsn ?? SentryDsn;
SentryTraceSampleRate = sentryTraceSampleRate ?? SentryTraceSampleRate;
ArenaParticipantsSyncInterval = arenaParticipantsSyncInterval ?? ArenaParticipantsSyncInterval;
}
}
}
15 changes: 12 additions & 3 deletions NineChronicles.Headless.Executable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ public async Task Run(
string? sentryDsn = "",
[Option(Description = "Trace sample rate for sentry")]
double? sentryTraceSampleRate = null,
[Option(Description = "arena participants list sync interval time")]
int? arenaParticipantsSyncInterval = null,
[Ignore] CancellationToken? cancellationToken = null
)
{
Expand Down Expand Up @@ -290,7 +292,7 @@ public async Task Run(
txLifeTime, messageTimeout, tipTimeout, demandBuffer, skipPreload,
minimumBroadcastTarget, bucketSize, chainTipStaleBehaviorType, txQuotaPerSigner, maximumPollPeers,
consensusPort, consensusPrivateKeyString, consensusSeedStrings, consensusTargetBlockIntervalMilliseconds,
sentryDsn, sentryTraceSampleRate
sentryDsn, sentryTraceSampleRate, arenaParticipantsSyncInterval
);

#if SENTRY || ! DEBUG
Expand Down Expand Up @@ -448,6 +450,7 @@ IActionLoader MakeSingleActionLoader()
MinerBlockInterval = minerBlockInterval,
TxQuotaPerSigner = headlessConfig.TxQuotaPerSigner,
};
var arenaMemoryCache = new StateMemoryCache();
hostBuilder.ConfigureServices(services =>
{
services.AddSingleton(_ => standaloneContext);
Expand All @@ -459,6 +462,10 @@ IActionLoader MakeSingleActionLoader()
.AddRuntimeInstrumentation()
.AddAspNetCoreInstrumentation()
.AddPrometheusExporter());

// worker
services.AddHostedService(_ => new ArenaParticipantsWorker(arenaMemoryCache, standaloneContext, headlessConfig.ArenaParticipantsSyncInterval));
services.AddSingleton(arenaMemoryCache);
});

NineChroniclesNodeService service =
Expand All @@ -485,7 +492,8 @@ IActionLoader MakeSingleActionLoader()
IPAddress.Loopback.ToString(),
rpcProperties.RpcListenPort,
context,
new ConcurrentDictionary<string, Sentry.ITransaction>()
new ConcurrentDictionary<string, Sentry.ITransaction>(),
arenaMemoryCache
);

hostBuilder.UseNineChroniclesNode(
Expand Down Expand Up @@ -515,7 +523,8 @@ IActionLoader MakeSingleActionLoader()
IPAddress.Loopback.ToString(),
0,
context,
new ConcurrentDictionary<string, Sentry.ITransaction>()
new ConcurrentDictionary<string, Sentry.ITransaction>(),
arenaMemoryCache
);
hostBuilder.UseNineChroniclesNode(
nineChroniclesProperties,
Expand Down
Loading

0 comments on commit 1045728

Please sign in to comment.