Skip to content

Instantly share code, notes, and snippets.

@dahlia
Last active April 9, 2019 08:43
Show Gist options
  • Save dahlia/7d6c9de74bbafba315dd2d30eaea18ed to your computer and use it in GitHub Desktop.
Save dahlia/7d6c9de74bbafba315dd2d30eaea18ed to your computer and use it in GitHub Desktop.
Trim Libplanet's last block. Download executables from <https://drive.google.com/drive/folders/1H599214BzuI4GImvfo6AKUydHV1tB-v8?usp=sharing>.
#!/usr/local/bin/pwsh
$target = "netcoreapp2.2"
$platforms = @("osx-x64","win-x64")
$results = @()
foreach ($rid in $platforms) {
dotnet publish -c Release -r $rid --self-contained true
$dest = "bin/Release/LibplanetBlockTrimmer.$rid.zip"
if (Test-Path $dest) {
Remove-Item $dest
}
Compress-Archive `
-Path bin/Release/$target/$rid/publish/* `
-DestinationPath $dest
$results += $dest
}
foreach ($dest in $results) {
echo $dest
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RootNamespace>LibplanetBlockTrimmer</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ben.Demystifier" Version="0.1.4" />
<PackageReference Include="Libplanet" Version="0.2.1" />
</ItemGroup>
</Project>
using Libplanet;
using Libplanet.Store;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace LibplanetBlockTrimmer
{
class Program
{
static int Main(string[] args)
{
try
{
return ProgramMain(args);
}
catch (Exception e)
{
Console.Error.WriteLine(e.Demystify());
return 1;
}
}
static int ProgramMain(string[] args)
{
TextWriter stderr = Console.Error;
string path = args.Length < 1 ? "." : args[0];
IStore store;
try
{
store = new FileStore(path);
}
catch (ArgumentException e)
{
stderr.WriteLine($"error: {e}");
Usage(stderr);
return 1;
}
HashSet<string> namespaces = store.ListNamespaces().ToHashSet();
if (namespaces.Count == 0)
{
stderr.WriteLine("error: There is no namespace at all.");
Usage(stderr);
return 1;
}
string ns;
if (namespaces.Count == 1)
{
ns = namespaces.First();
stderr.WriteLine(
$"There is only one namespace: {ns}; use this."
);
}
else if (args.Length > 1)
{
ns = args[1];
}
else
{
stderr.WriteLine(
"error: There are multiple namespaces. Please choose " +
"one in the following namespaces:"
);
foreach (string n in namespaces)
{
stderr.WriteLine($"\t{n}");
}
Usage(stderr);
return 1;
}
long tipIndex = store.CountIndex(ns) - 1;
HashDigest<SHA256>? tipHash = store.IndexBlockHash(ns, tipIndex);
if (tipIndex < 0 || !tipHash.HasValue)
{
stderr.WriteLine("error: There is no block at all.");
return 1;
}
stderr.WriteLine(
$"The tip before trimming: {tipHash.Value} ({tipIndex})."
);
bool deleted = store.DeleteIndex(ns, tipHash.Value);
if (!deleted)
{
stderr.WriteLine(
$"error: Failed to trim the block {tipHash} ({tipIndex})."
);
return 1;
}
tipIndex = store.CountIndex(ns) - 1;
tipHash = store.IndexBlockHash(ns, tipIndex);
TextWriter stdout = Console.Out;
stderr.Write("The tip after timmed: ");
stderr.Flush();
stdout.Write($"{tipHash} ({tipIndex})");
stdout.Flush();
stderr.WriteLine(".");
return 0;
}
private static void Usage(TextWriter writer)
{
string name = System.Environment.GetCommandLineArgs()[0];
writer.WriteLine($"usage: {name} [PATH] [NAMESPACE]");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment